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

📄 c67-gen.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  TMS320C67xx code generator for TCC *  *  Copyright (c) 2001, 2002 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *///#define ASSEMBLY_LISTING_C67/* number of available registers */#define NB_REGS            24/* a register can belong to several classes. The classes must be   sorted from more general to more precise (see gv2() code which does   assumptions on it). */#define RC_INT     0x0001	/* generic integer register */#define RC_FLOAT   0x0002	/* generic float register */#define RC_EAX     0x0004#define RC_ST0     0x0008#define RC_ECX     0x0010#define RC_EDX     0x0020#define RC_INT_BSIDE  0x00000040	/* generic integer register  on b side */#define RC_C67_A4     0x00000100#define RC_C67_A5     0x00000200#define RC_C67_B4     0x00000400#define RC_C67_B5     0x00000800#define RC_C67_A6     0x00001000#define RC_C67_A7     0x00002000#define RC_C67_B6     0x00004000#define RC_C67_B7     0x00008000#define RC_C67_A8     0x00010000#define RC_C67_A9     0x00020000#define RC_C67_B8     0x00040000#define RC_C67_B9     0x00080000#define RC_C67_A10    0x00100000#define RC_C67_A11    0x00200000#define RC_C67_B10    0x00400000#define RC_C67_B11    0x00800000#define RC_C67_A12    0x01000000#define RC_C67_A13    0x02000000#define RC_C67_B12    0x04000000#define RC_C67_B13    0x08000000#define RC_IRET    RC_C67_A4	/* function return: integer register */#define RC_LRET    RC_C67_A5	/* function return: second integer register */#define RC_FRET    RC_C67_A4	/* function return: float register *//* pretty names for the registers */enum {    TREG_EAX = 0,		// really A2    TREG_ECX,			// really A3    TREG_EDX,			// really B0    TREG_ST0,			// really B1    TREG_C67_A4,    TREG_C67_A5,    TREG_C67_B4,    TREG_C67_B5,    TREG_C67_A6,    TREG_C67_A7,    TREG_C67_B6,    TREG_C67_B7,    TREG_C67_A8,    TREG_C67_A9,    TREG_C67_B8,    TREG_C67_B9,    TREG_C67_A10,    TREG_C67_A11,    TREG_C67_B10,    TREG_C67_B11,    TREG_C67_A12,    TREG_C67_A13,    TREG_C67_B12,    TREG_C67_B13,};int reg_classes[NB_REGS] = {						/* eax */ RC_INT | RC_FLOAT | RC_EAX,						// only allow even regs for floats (allow for doubles)    /* ecx */ RC_INT | RC_ECX,								/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,								// only allow even regs for floats (allow for doubles)    /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,    /* A4  */ RC_C67_A4,    /* A5  */ RC_C67_A5,    /* B4  */ RC_C67_B4,    /* B5  */ RC_C67_B5,    /* A6  */ RC_C67_A6,    /* A7  */ RC_C67_A7,    /* B6  */ RC_C67_B6,    /* B7  */ RC_C67_B7,    /* A8  */ RC_C67_A8,    /* A9  */ RC_C67_A9,    /* B8  */ RC_C67_B8,    /* B9  */ RC_C67_B9,    /* A10  */ RC_C67_A10,    /* A11  */ RC_C67_A11,    /* B10  */ RC_C67_B10,    /* B11  */ RC_C67_B11,    /* A12  */ RC_C67_A10,    /* A13  */ RC_C67_A11,    /* B12  */ RC_C67_B10,    /* B13  */ RC_C67_B11};/* return registers for function */#define REG_IRET TREG_C67_A4	/* single word int return register */#define REG_LRET TREG_C67_A5	/* second word return register (for long long) */#define REG_FRET TREG_C67_A4	/* float return register */#define ALWAYS_ASSERT(x) \do {\   if (!(x))\       error("internal compiler error file at %s:%d", __FILE__, __LINE__);\} while (0)// although tcc thinks it is passing parameters on the stack,// the C67 really passes up to the first 10 params in special// regs or regs pairs (for 64 bit params).  So keep track of// the stack offsets so we can translate to the appropriate // reg (pair)#define NoCallArgsPassedOnStack 10int NoOfCurFuncArgs;int TranslateStackToReg[NoCallArgsPassedOnStack];int ParamLocOnStack[NoCallArgsPassedOnStack];int TotalBytesPushedOnStack;/* defined if function parameters must be evaluated in reverse order *///#define INVERT_FUNC_PARAMS/* defined if structures are passed as pointers. Otherwise structures   are directly pushed on stack. *///#define FUNC_STRUCT_PARAM_AS_PTR/* pointer size, in bytes */#define PTR_SIZE 4/* long double size and alignment, in bytes */#define LDOUBLE_SIZE  12#define LDOUBLE_ALIGN 4/* maximum alignment (for aligned attribute support) */#define MAX_ALIGN     8/******************************************************//* ELF defines */#define EM_TCC_TARGET EM_C60/* relocation type for 32 bit data relocation */#define R_DATA_32   R_C60_32#define R_JMP_SLOT  R_C60_JMP_SLOT#define R_COPY      R_C60_COPY#define ELF_START_ADDR 0x00000400#define ELF_PAGE_SIZE  0x1000/******************************************************/static unsigned long func_sub_sp_offset;static int func_ret_sub;static BOOL C67_invert_test;static int C67_compare_reg;#ifdef ASSEMBLY_LISTING_C67FILE *f = NULL;#endifvoid C67_g(int c){    int ind1;#ifdef ASSEMBLY_LISTING_C67    fprintf(f, " %08X", c);#endif    ind1 = ind + 4;    if (ind1 > (int) cur_text_section->data_allocated)	section_realloc(cur_text_section, ind1);    cur_text_section->data[ind] = c & 0xff;    cur_text_section->data[ind + 1] = (c >> 8) & 0xff;    cur_text_section->data[ind + 2] = (c >> 16) & 0xff;    cur_text_section->data[ind + 3] = (c >> 24) & 0xff;    ind = ind1;}/* output a symbol and patch all calls to it */void gsym_addr(int t, int a){    int n, *ptr;    while (t) {	ptr = (int *) (cur_text_section->data + t);	{	    Sym *sym;	    // extract 32 bit address from MVKH/MVKL	    n = ((*ptr >> 7) & 0xffff);	    n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;	    // define a label that will be relocated	    sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);	    greloc(cur_text_section, sym, t, R_C60LO16);	    greloc(cur_text_section, sym, t + 4, R_C60HI16);	    // clear out where the pointer was	    *ptr &= ~(0xffff << 7);	    *(ptr + 1) &= ~(0xffff << 7);	}	t = n;    }}void gsym(int t){    gsym_addr(t, ind);}// these are regs that tcc doesn't really know about, // but asign them unique values so the mapping routines// can distinquish them#define C67_A0 105#define C67_SP 106#define C67_B3 107#define C67_FP 108#define C67_B2 109#define C67_CREG_ZERO -1	// Special code for no condition reg testint ConvertRegToRegClass(int r){    // only works for A4-B13    return RC_C67_A4 << (r - TREG_C67_A4);}// map TCC reg to C67 reg numberint C67_map_regn(int r){    if (r == 0)			// normal tcc regs	return 0x2;		// A2    else if (r == 1)		// normal tcc regs	return 3;		// A3    else if (r == 2)		// normal tcc regs	return 0;		// B0    else if (r == 3)		// normal tcc regs	return 1;		// B1    else if (r >= TREG_C67_A4 && r <= TREG_C67_B13)	// these form a pattern of alt pairs	return (((r & 0xfffffffc) >> 1) | (r & 1)) + 2;    else if (r == C67_A0)	return 0;		// set to A0 (offset reg)    else if (r == C67_B2)	return 2;		// set to B2 (offset reg)    else if (r == C67_B3)	return 3;		// set to B3 (return address reg)    else if (r == C67_SP)	return 15;		// set to SP (B15) (offset reg)    else if (r == C67_FP)	return 15;		// set to FP (A15) (offset reg)    else if (r == C67_CREG_ZERO)	return 0;		// Special code for no condition reg test    else	ALWAYS_ASSERT(FALSE);    return 0;}// mapping from tcc reg number to // C67 register to condition code field//// valid condition code regs are://// tcc reg 2 ->B0 -> 1// tcc reg 3 ->B1 -> 2// tcc reg 0 -> A2 -> 5// tcc reg 1 -> A3 -> X// tcc reg      B2 -> 3int C67_map_regc(int r){    if (r == 0)			// normal tcc regs	return 0x5;    else if (r == 2)		// normal tcc regs	return 0x1;    else if (r == 3)		// normal tcc regs	return 0x2;    else if (r == C67_B2)	// normal tcc regs	return 0x3;    else if (r == C67_CREG_ZERO)	return 0;		// Special code for no condition reg test    else	ALWAYS_ASSERT(FALSE);    return 0;}// map TCC reg to C67 reg side A or Bint C67_map_regs(int r){    if (r == 0)			// normal tcc regs	return 0x0;    else if (r == 1)		// normal tcc regs	return 0x0;    else if (r == 2)		// normal tcc regs	return 0x1;    else if (r == 3)		// normal tcc regs	return 0x1;    else if (r >= TREG_C67_A4 && r <= TREG_C67_B13)	// these form a pattern of alt pairs	return (r & 2) >> 1;    else if (r == C67_A0)	return 0;		// set to A side     else if (r == C67_B2)	return 1;		// set to B side     else if (r == C67_B3)	return 1;		// set to B side    else if (r == C67_SP)	return 0x1;		// set to SP (B15) B side     else if (r == C67_FP)	return 0x0;		// set to FP (A15) A side     else	ALWAYS_ASSERT(FALSE);    return 0;}int C67_map_S12(char *s){    if (strstr(s, ".S1") != NULL)	return 0;    else if (strcmp(s, ".S2"))	return 1;    else	ALWAYS_ASSERT(FALSE);    return 0;}int C67_map_D12(char *s){    if (strstr(s, ".D1") != NULL)	return 0;    else if (strcmp(s, ".D2"))	return 1;    else	ALWAYS_ASSERT(FALSE);    return 0;}void C67_asm(char *s, int a, int b, int c){    BOOL xpath;#ifdef ASSEMBLY_LISTING_C67    if (!f) {	f = fopen("TCC67_out.txt", "wt");    }    fprintf(f, "%04X ", ind);#endif    if (strstr(s, "MVKL") == s) {	C67_g((C67_map_regn(b) << 23) |	      ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));    } else if (strstr(s, "MVKH") == s) {	C67_g((C67_map_regn(b) << 23) |	      (((a >> 16) & 0xffff) << 7) |	      (0x1a << 2) | (C67_map_regs(b) << 1));    } else if (strstr(s, "STW.D SP POST DEC") == s) {	C67_g((C67_map_regn(a) << 23) |	//src	      (15 << 18) |	//SP B15	      (2 << 13) |	//ucst5 (must keep 8 byte boundary !!)	      (0xa << 9) |	//mode a = post dec ucst	      (0 << 8) |	//r (LDDW bit 0)	      (1 << 7) |	//y D1/D2 use B side	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU	      (1 << 2) |	//opcode	      (C67_map_regs(a) << 1) |	//side of src	      (0 << 0));	//parallel    } else if (strstr(s, "STB.D *+SP[A0]") == s) {	C67_g((C67_map_regn(a) << 23) |	//src	      (15 << 18) |	//base reg A15	      (0 << 13) |	//offset reg A0	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg	      (0 << 8) |	//r (LDDW bit 0)	      (0 << 7) |	//y D1/D2 A side	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 	      (1 << 2) |	//opcode	      (C67_map_regs(a) << 1) |	//side of src	      (0 << 0));	//parallel    } else if (strstr(s, "STH.D *+SP[A0]") == s) {	C67_g((C67_map_regn(a) << 23) |	//src	      (15 << 18) |	//base reg A15	      (0 << 13) |	//offset reg A0	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg	      (0 << 8) |	//r (LDDW bit 0)	      (0 << 7) |	//y D1/D2 A side	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU	      (1 << 2) |	//opcode	      (C67_map_regs(a) << 1) |	//side of src	      (0 << 0));	//parallel    } else if (strstr(s, "STB.D *+SP[A0]") == s) {	C67_g((C67_map_regn(a) << 23) |	//src	      (15 << 18) |	//base reg A15	      (0 << 13) |	//offset reg A0	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg	      (0 << 8) |	//r (LDDW bit 0)	      (0 << 7) |	//y D1/D2 A side	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 	      (1 << 2) |	//opcode	      (C67_map_regs(a) << 1) |	//side of src	      (0 << 0));	//parallel    } else if (strstr(s, "STH.D *+SP[A0]") == s) {	C67_g((C67_map_regn(a) << 23) |	//src	      (15 << 18) |	//base reg A15	      (0 << 13) |	//offset reg A0	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg	      (0 << 8) |	//r (LDDW bit 0)	      (0 << 7) |	//y D1/D2 A side	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU	      (1 << 2) |	//opcode	      (C67_map_regs(a) << 1) |	//side of src	      (0 << 0));	//parallel    } else if (strstr(s, "STW.D *+SP[A0]") == s) {	C67_g((C67_map_regn(a) << 23) |	//src	      (15 << 18) |	//base reg A15	      (0 << 13) |	//offset reg A0	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg	      (0 << 8) |	//r (LDDW bit 0)	      (0 << 7) |	//y D1/D2 A side	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 	      (1 << 2) |	//opcode

⌨️ 快捷键说明

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