Alien-TinyCC
view release on metacpan or search on metacpan
src/c67-gen.c view on Meta::CPAN
C67_MV(C67_FP, C67_A0); // move FP -> A0
C67_MV(C67_SP, C67_FP); // move SP -> FP
// place all the args passed in regs onto the stack
loc = 0;
for (i = 0; i < NoOfCurFuncArgs; i++) {
ParamLocOnStack[i] = loc; // remember where the param is
loc += -8;
C67_PUSH(TREG_C67_A4 + i * 2);
if (TranslateStackToReg[i] == 8) {
C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other)
}
}
TotalBytesPushedOnStack = -loc;
func_sub_sp_offset = ind; // remember where we put the stack instruction
C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
C67_PUSH(C67_A0);
C67_PUSH(C67_B3);
}
/* generate function epilog */
void gfunc_epilog(void)
{
{
int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
C67_POP(C67_B3);
C67_NOP(4); // NOP wait for load
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
C67_POP(C67_FP);
C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
C67_Adjust_ADDK((int *) (cur_text_section->data +
func_sub_sp_offset),
-local + TotalBytesPushedOnStack);
C67_NOP(3); // NOP
}
}
/* generate a jump to a label */
int gjmp(int t)
{
int ind1 = ind;
C67_MVKL(C67_A0, t); //r=reg to load, constant
C67_MVKH(C67_A0, t); //r=reg to load, constant
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0
C67_NOP(5);
return ind1;
}
/* generate a jump to a fixed address */
void gjmp_addr(int a)
{
Sym *sym;
// I guess this routine is used for relative short
// local jumps, for now just handle it as the general
// case
// define a label that will be relocated
sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
greloc(cur_text_section, sym, ind, R_C60LO16);
greloc(cur_text_section, sym, ind + 4, R_C60HI16);
gjmp(0); // place a zero there later the symbol will be added to it
}
/* generate a test. set 'inv' to invert test. Stack entry is popped */
int gtst(int inv, int t)
{
int ind1, n;
int v, *p;
v = vtop->r & VT_VALMASK;
if (v == VT_CMP) {
/* fast case : can jump directly since flags are set */
// C67 uses B2 sort of as flags register
ind1 = ind;
C67_MVKL(C67_A0, t); //r=reg to load, constant
C67_MVKH(C67_A0, t); //r=reg to load, constant
if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg
C67_compare_reg != TREG_EDX &&
C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {
C67_MV(C67_compare_reg, C67_B2);
C67_compare_reg = C67_B2;
}
C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0
C67_NOP(5);
t = ind1; //return where we need to patch
} else if (v == VT_JMP || v == VT_JMPI) {
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
p = &vtop->c.i;
// I guess the idea is to traverse to the
// null at the end of the list and store t
// there
n = *p;
while (n != 0) {
p = (int *) (cur_text_section->data + n);
// extract 32 bit address from MVKH/MVKL
n = ((*p >> 7) & 0xffff);
n |= ((*(p + 1) >> 7) & 0xffff) << 16;
}
*p |= (t & 0xffff) << 7;
*(p + 1) |= ((t >> 16) & 0xffff) << 7;
t = vtop->c.i;
} else {
t = gjmp(t);
gsym(vtop->c.i);
}
} else {
if (is_float(vtop->type.t)) {
vpushi(0);
gen_op(TOK_NE);
}
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
/* constant jmp optimization */
if ((vtop->c.i != 0) != inv)
t = gjmp(t);
} else {
// I think we need to get the value on the stack
// into a register, test it, and generate a branch
// return the address of the branch, so it can be
// later patched
v = gv(RC_INT); // get value into a reg
ind1 = ind;
C67_MVKL(C67_A0, t); //r=reg to load, constant
C67_MVKH(C67_A0, t); //r=reg to load, constant
if (v != TREG_EAX && // check if not already in a conditional test reg
v != TREG_EDX && v != TREG_ST0 && v != C67_B2) {
C67_MV(v, C67_B2);
v = C67_B2;
}
C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0
C67_NOP(5);
t = ind1; //return where we need to patch
ind1 = ind;
}
}
vtop--;
return t;
}
/* generate an integer binary operation */
void gen_opi(int op)
{
int r, fr, opc, t;
( run in 1.239 second using v1.01-cache-2.11-cpan-e1769b4cff6 )