Alien-TinyCC

 view release on metacpan or  search on metacpan

src/c67-gen.c  view on Meta::CPAN

    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

src/c67-gen.c  view on Meta::CPAN

    fc = vtop->c.ul;
    r = vtop->r;
    fr = vtop[-1].r;


    if ((ft & VT_BTYPE) == VT_LDOUBLE)
	tcc_error("long doubles not supported");

    if (op >= TOK_ULT && op <= TOK_GT) {

	r = vtop[-1].r;
	fr = vtop[0].r;

	C67_compare_reg = C67_B2;

	if (op == TOK_LT) {
	    if ((ft & VT_BTYPE) == VT_DOUBLE)
		C67_CMPLTDP(r, fr, C67_B2);
	    else
		C67_CMPLTSP(r, fr, C67_B2);

	    C67_invert_test = FALSE;
	} else if (op == TOK_GE) {
	    if ((ft & VT_BTYPE) == VT_DOUBLE)
		C67_CMPLTDP(r, fr, C67_B2);
	    else
		C67_CMPLTSP(r, fr, C67_B2);

	    C67_invert_test = TRUE;
	} else if (op == TOK_GT) {
	    if ((ft & VT_BTYPE) == VT_DOUBLE)
		C67_CMPGTDP(r, fr, C67_B2);
	    else
		C67_CMPGTSP(r, fr, C67_B2);

	    C67_invert_test = FALSE;
	} else if (op == TOK_LE) {
	    if ((ft & VT_BTYPE) == VT_DOUBLE)
		C67_CMPGTDP(r, fr, C67_B2);
	    else
		C67_CMPGTSP(r, fr, C67_B2);

	    C67_invert_test = TRUE;
	} else if (op == TOK_EQ) {
	    if ((ft & VT_BTYPE) == VT_DOUBLE)
		C67_CMPEQDP(r, fr, C67_B2);
	    else
		C67_CMPEQSP(r, fr, C67_B2);

	    C67_invert_test = FALSE;
	} else if (op == TOK_NE) {
	    if ((ft & VT_BTYPE) == VT_DOUBLE)
		C67_CMPEQDP(r, fr, C67_B2);
	    else
		C67_CMPEQSP(r, fr, C67_B2);

	    C67_invert_test = TRUE;
	} else {
	    ALWAYS_ASSERT(FALSE);
	}
	vtop->r = VT_CMP;	// tell TCC that result is in "flags" actually B2
    } else {
	if (op == '+') {
	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
		C67_ADDDP(r, fr);	// ADD  fr,r,fr
		C67_NOP(6);
	    } else {
		C67_ADDSP(r, fr);	// ADD  fr,r,fr
		C67_NOP(3);
	    }
	    vtop--;
	} else if (op == '-') {
	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
		C67_SUBDP(r, fr);	// SUB  fr,r,fr
		C67_NOP(6);
	    } else {
		C67_SUBSP(r, fr);	// SUB  fr,r,fr
		C67_NOP(3);
	    }
	    vtop--;
	} else if (op == '*') {
	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
		C67_MPYDP(r, fr);	// MPY  fr,r,fr
		C67_NOP(9);
	    } else {
		C67_MPYSP(r, fr);	// MPY  fr,r,fr
		C67_NOP(3);
	    }
	    vtop--;
	} else if (op == '/') {
	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
		// must call intrinsic DP floating point divide
		vswap();
		/* call generic idiv function */
		vpush_global_sym(&func_old_type, TOK__divd);
		vrott(3);
		gfunc_call(2);
		vpushi(0);
		vtop->r = REG_FRET;
		vtop->r2 = REG_LRET;

	    } else {
		// must call intrinsic SP floating point divide
		vswap();
		/* call generic idiv function */
		vpush_global_sym(&func_old_type, TOK__divf);
		vrott(3);
		gfunc_call(2);
		vpushi(0);
		vtop->r = REG_FRET;
		vtop->r2 = VT_CONST;
	    }
	} else
	    ALWAYS_ASSERT(FALSE);


    }
}


/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'



( run in 0.532 second using v1.01-cache-2.11-cpan-9bca49b1385 )