⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c67-gen.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
void C67_CMPGTDP(int s1, int s2, int dst){    C67_asm("CMPGTDP.S1", s1, s2, dst);}void C67_CMPEQDP(int s1, int s2, int dst){    C67_asm("CMPEQDP.S1", s1, s2, dst);}void C67_IREG_B_REG(int inv, int r1, int r2)	// [!R] B  r2{    C67_asm("B.S2", inv, r1, r2);}// call with how many 32 bit words to skip// (0 would branch to the branch instruction)void C67_B_DISP(int disp)	//  B  +2  Branch with constant displacement{    // Branch point is relative to the 8 word fetch packet    //    // we will assume the text section always starts on an 8 word (32 byte boundary)    //    // so add in how many words into the fetch packet the branch is    C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);}void C67_NOP(int n){    C67_asm("NOP", n, 0, 0);}void C67_ADDK(int n, int r){    ALWAYS_ASSERT(abs(n) < 32767);    C67_asm("ADDK", n, r, 0);}void C67_ADDK_PARALLEL(int n, int r){    ALWAYS_ASSERT(abs(n) < 32767);    C67_asm("||ADDK", n, r, 0);}void C67_Adjust_ADDK(int *inst, int n){    ALWAYS_ASSERT(abs(n) < 32767);    *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);}void C67_MV(int r, int v){    C67_asm("MV.L", 0, r, v);}void C67_DPTRUNC(int r, int v){    C67_asm("DPTRUNC.L", 0, r, v);}void C67_SPTRUNC(int r, int v){    C67_asm("SPTRUNC.L", 0, r, v);}void C67_INTSP(int r, int v){    C67_asm("INTSP.L", 0, r, v);}void C67_INTDP(int r, int v){    C67_asm("INTDP.L", 0, r, v);}void C67_INTSPU(int r, int v){    C67_asm("INTSPU.L", 0, r, v);}void C67_INTDPU(int r, int v){    C67_asm("INTDPU.L", 0, r, v);}void C67_SPDP(int r, int v){    C67_asm("SPDP.L", 0, r, v);}void C67_DPSP(int r, int v)	// note regs must be on the same side{    C67_asm("DPSP.L", 0, r, v);}void C67_ADD(int r, int v){    C67_asm("ADD.L", v, r, v);}void C67_SUB(int r, int v){    C67_asm("SUB.L", v, r, v);}void C67_AND(int r, int v){    C67_asm("AND.L", v, r, v);}void C67_OR(int r, int v){    C67_asm("OR.L", v, r, v);}void C67_XOR(int r, int v){    C67_asm("XOR.L", v, r, v);}void C67_ADDSP(int r, int v){    C67_asm("ADDSP.L", v, r, v);}void C67_SUBSP(int r, int v){    C67_asm("SUBSP.L", v, r, v);}void C67_MPYSP(int r, int v){    C67_asm("MPYSP.M", v, r, v);}void C67_ADDDP(int r, int v){    C67_asm("ADDDP.L", v, r, v);}void C67_SUBDP(int r, int v){    C67_asm("SUBDP.L", v, r, v);}void C67_MPYDP(int r, int v){    C67_asm("MPYDP.M", v, r, v);}void C67_MPYI(int r, int v){    C67_asm("MPYI.M", v, r, v);}void C67_SHL(int r, int v){    C67_asm("SHL.S", r, v, v);}void C67_SHRU(int r, int v){    C67_asm("SHRU.S", r, v, v);}void C67_SHR(int r, int v){    C67_asm("SHR.S", r, v, v);}/* load 'r' from value 'sv' */void load(int r, SValue * sv){    int v, t, ft, fc, fr, size = 0, element;    BOOL Unsigned = false;    SValue v1;    fr = sv->r;    ft = sv->type.t;    fc = sv->c.ul;    v = fr & VT_VALMASK;    if (fr & VT_LVAL) {	if (v == VT_LLOCAL) {	    v1.type.t = VT_INT;	    v1.r = VT_LOCAL | VT_LVAL;	    v1.c.ul = fc;	    load(r, &v1);	    fr = r;	} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {	    error("long double not supported");	} else if ((ft & VT_TYPE) == VT_BYTE) {	    size = 1;	} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {	    size = 1;	    Unsigned = TRUE;	} else if ((ft & VT_TYPE) == VT_SHORT) {	    size = 2;	} else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {	    size = 2;	    Unsigned = TRUE;	} else if ((ft & VT_BTYPE) == VT_DOUBLE) {	    size = 8;	} else {	    size = 4;	}	// check if fc is a positive reference on the stack, 	// if it is tcc is referencing what it thinks is a parameter	// on the stack, so check if it is really in a register.	if (v == VT_LOCAL && fc > 0) {	    int stack_pos = 8;	    for (t = 0; t < NoCallArgsPassedOnStack; t++) {		if (fc == stack_pos)		    break;		stack_pos += TranslateStackToReg[t];	    }	    // param has been pushed on stack, get it like a local var	    fc = ParamLocOnStack[t] - 8;	}	if ((fr & VT_VALMASK) < VT_CONST)	// check for pure indirect	{	    if (size == 1) {		if (Unsigned)		    C67_LDBU_PTR(v, r);	// LDBU  *v,r		else		    C67_LDB_PTR(v, r);	// LDB  *v,r	    } else if (size == 2) {		if (Unsigned)		    C67_LDHU_PTR(v, r);	// LDHU  *v,r		else		    C67_LDH_PTR(v, r);	// LDH  *v,r	    } else if (size == 4) {		C67_LDW_PTR(v, r);	// LDW  *v,r	    } else if (size == 8) {		C67_LDDW_PTR(v, r);	// LDDW  *v,r	    }	    C67_NOP(4);		// NOP 4	    return;	} else if (fr & VT_SYM) {	    greloc(cur_text_section, sv->sym, ind, R_C60LO16);	// rem the inst need to be patched	    greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);	    C67_MVKL(C67_A0, fc);	//r=reg to load,  constant	    C67_MVKH(C67_A0, fc);	//r=reg to load,  constant	    if (size == 1) {		if (Unsigned)		    C67_LDBU_PTR(C67_A0, r);	// LDBU  *A0,r		else		    C67_LDB_PTR(C67_A0, r);	// LDB  *A0,r	    } else if (size == 2) {		if (Unsigned)		    C67_LDHU_PTR(C67_A0, r);	// LDHU  *A0,r		else		    C67_LDH_PTR(C67_A0, r);	// LDH  *A0,r	    } else if (size == 4) {		C67_LDW_PTR(C67_A0, r);	// LDW  *A0,r	    } else if (size == 8) {		C67_LDDW_PTR(C67_A0, r);	// LDDW  *A0,r	    }	    C67_NOP(4);		// NOP 4	    return;	} else {	    element = size;	    // divide offset in bytes to create element index	    C67_MVKL(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant	    C67_MVKH(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant	    if (size == 1) {		if (Unsigned)		    C67_LDBU_SP_A0(r);	// LDBU  r, SP[A0]		else		    C67_LDB_SP_A0(r);	// LDB  r, SP[A0]	    } else if (size == 2) {		if (Unsigned)		    C67_LDHU_SP_A0(r);	// LDHU  r, SP[A0]		else		    C67_LDH_SP_A0(r);	// LDH  r, SP[A0]	    } else if (size == 4) {		C67_LDW_SP_A0(r);	// LDW  r, SP[A0]	    } else if (size == 8) {		C67_LDDW_SP_A0(r);	// LDDW  r, SP[A0]	    }	    C67_NOP(4);		// NOP 4	    return;	}    } else {	if (v == VT_CONST) {	    if (fr & VT_SYM) {		greloc(cur_text_section, sv->sym, ind, R_C60LO16);	// rem the inst need to be patched		greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);	    }	    C67_MVKL(r, fc);	//r=reg to load, constant	    C67_MVKH(r, fc);	//r=reg to load, constant	} else if (v == VT_LOCAL) {	    C67_MVKL(r, fc + 8);	//r=reg to load, constant C67 stack points to next free	    C67_MVKH(r, fc + 8);	//r=reg to load, constant	    C67_ADD(C67_FP, r);	// MV v,r   v -> r	} else if (v == VT_CMP) {	    C67_MV(C67_compare_reg, r);	// MV v,r   v -> r	} else if (v == VT_JMP || v == VT_JMPI) {	    t = v & 1;	    C67_B_DISP(4);	//  Branch with constant displacement, skip over this branch, load, nop, load	    C67_MVKL(r, t);	//  r=reg to load, 0 or 1 (do this while branching)	    C67_NOP(4);		//  NOP 4	    gsym(fc);		//  modifies other branches to branch here	    C67_MVKL(r, t ^ 1);	//  r=reg to load, 0 or 1	} else if (v != r) {	    C67_MV(v, r);	// MV v,r   v -> r	    if ((ft & VT_BTYPE) == VT_DOUBLE)		C67_MV(v + 1, r + 1);	// MV v,r   v -> r	}    }}/* store register 'r' in lvalue 'v' */void store(int r, SValue * v){    int fr, bt, ft, fc, size, t, element;    ft = v->type.t;    fc = v->c.ul;    fr = v->r & VT_VALMASK;    bt = ft & VT_BTYPE;    /* XXX: incorrect if float reg to reg */    if (bt == VT_LDOUBLE) {	error("long double not supported");    } else {	if (bt == VT_SHORT)	    size = 2;	else if (bt == VT_BYTE)	    size = 1;	else if (bt == VT_DOUBLE)	    size = 8;	else	    size = 4;	if ((v->r & VT_VALMASK) == VT_CONST) {	    /* constant memory reference */	    if (v->r & VT_SYM) {		greloc(cur_text_section, v->sym, ind, R_C60LO16);	// rem the inst need to be patched		greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);	    }	    C67_MVKL(C67_A0, fc);	//r=reg to load,  constant	    C67_MVKH(C67_A0, fc);	//r=reg to load,  constant	    if (size == 1)		C67_STB_PTR(r, C67_A0);	// STB  r, *A0	    else if (size == 2)		C67_STH_PTR(r, C67_A0);	// STH  r, *A0	    else if (size == 4 || size == 8)		C67_STW_PTR(r, C67_A0);	// STW  r, *A0	    if (size == 8)		C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1);	// STW  r, *+A0[1]	} else if ((v->r & VT_VALMASK) == VT_LOCAL) {	    // check case of storing to passed argument that	    // tcc thinks is on the stack but for C67 is	    // passed as a reg.  However it may have been	    // saved to the stack, if that reg was required	    // for a call to a child function	    if (fc > 0)		// argument ??	    {		// walk through sizes and figure which param		int stack_pos = 8;		for (t = 0; t < NoCallArgsPassedOnStack; t++) {		    if (fc == stack_pos)			break;		    stack_pos += TranslateStackToReg[t];		}		// param has been pushed on stack, get it like a local var		fc = ParamLocOnStack[t] - 8;	    }	    if (size == 8)		element = 4;	    else		element = size;	    // divide offset in bytes to create word index	    C67_MVKL(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant	    C67_MVKH(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant	    if (size == 1)		C67_STB_SP_A0(r);	// STB  r, SP[A0]	    else if (size == 2)		C67_STH_SP_A0(r);	// STH  r, SP[A0]	    else if (size == 4 || size == 8)		C67_STW_SP_A0(r);	// STW  r, SP[A0]	    if (size == 8) {		C67_ADDK(1, C67_A0);	//  ADDK 1,A0		C67_STW_SP_A0(r + 1);	//  STW  r, SP[A0]	    }	} else {	    if (size == 1)		C67_STB_PTR(r, fr);	// STB  r, *fr	    else if (size == 2)		C67_STH_PTR(r, fr);	// STH  r, *fr	    else if (size == 4 || size == 8)		C67_STW_PTR(r, fr);	// STW  r, *fr	    if (size == 8) {		C67_STW_PTR_PRE_INC(r + 1, fr, 1);	// STW  r, *+fr[1]	    }	}    }}/* 'is_jmp' is '1' if it is a jump */static void gcall_or_jmp(int is_jmp){    int r;    Sym *sym;    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {	/* constant case */	if (vtop->r & VT_SYM) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -