Mercurial > hg > CbC > old > device
changeset 733:116d4701d097
i64 continue
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 04 Nov 2010 23:18:42 +0900 |
parents | 7a4f389b5bc0 |
children | d2d6b1ef2cb4 |
files | Changes mc-code-i64.c mc-code-ia32.c |
diffstat | 3 files changed, 272 insertions(+), 269 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Thu Nov 04 21:10:20 2010 +0900 +++ b/Changes Thu Nov 04 23:18:42 2010 +0900 @@ -9848,4 +9848,8 @@ そうすれば、goto 文は、かなり簡単になる。 - +Thu Nov 4 22:47:08 JST 2010 + +LP64 だと、scalar の扱いをなんとかしないと。 + +
--- a/mc-code-i64.c Thu Nov 04 21:10:20 2010 +0900 +++ b/mc-code-i64.c Thu Nov 04 23:18:42 2010 +0900 @@ -260,9 +260,9 @@ int code_lassop_p = 0; -#define MAX_REGISTER 14 /* intel386のレジスタを6つまで使う*/ -#define REAL_MAX_REGISTER 16 /* intel386のレジスタが8つということ*/ -int MAX_REGISTER_VAR=8; +#define MAX_REGISTER 14 /* intel386のレジスタを6つまで使う*/ +#define REAL_MAX_REGISTER (1+16+16) /* intel386のレジスタが8つということ*/ +int MAX_REGISTER_VAR=6; static int MAX_DREGISTER=16; int MAX_DREGISTER_VAR=8; @@ -322,10 +322,8 @@ kept in FPU stack (no register) */ -#define REAL_MAX_LREGISTER 2 static int ia32regs[1+REAL_MAX_REGISTER]; - static int *regs = ia32regs; static int ia32fregs[1+MAX_DREGISTER]; @@ -340,25 +338,26 @@ // 2 (REG_VAR) register variable // 3 pointer cache (not used in ia32) -#define REG_EBP 1 -#define REG_ESP 2 +#define REG_ESP 1 +#define REG_EBP 2 #define REG_EDI 3 // first argument register #define REG_ESI 4 #define REG_EDX 5 #define REG_ECX 6 // for strange reason (code_assop) #define REG_EAX 7 #define REG_EBX 8 -#define is_int_reg(reg) 1 // (1<=reg&®<REG_EBP) +#define is_int_reg(reg) (1<=reg&®<MAX_REGISTER) +#define is_float_reg(reg) (RET_FREGISTER<=reg&®<REAL_MAX_REGISTER) // return value register -#define RET_FREGISTER 1 -#define RET_DREGISTER 1 +#define RET_FREGISTER 18 +#define RET_DREGISTER 18 #define RET_LREGISTER REG_EAX #define RET_REGISTER REG_EAX // defalut current register #define CREG_REGISTER REG_ECX -#define FREG_FREGISTER 2 +#define FREG_FREGISTER 19 static char *reg_name_l[] = {0, 0, @@ -416,6 +415,12 @@ "%r15d", "%r16d"}; +#define REG_VAR_BASE (RET_FREGISTER-1) +#define REG_VAR_MIN (RET_FREGISTER-1-MAX_REGISTER_VAR) + +#define FREG_VAR_BASE (RET_FREGISTER+16) +#define FREG_VAR_MIN (RET_FREGISTER+16-MAX_DREGISTER_VAR) + static char *reg_name_q[] = {0, "%rsp", "%rbp", @@ -433,10 +438,8 @@ "%r13", "%r14", "%r15", - "%r16"}; - -static char *reg_name_q[16+1] = {0, - "%xmm0", + "%r16", + "%xmm0", // 18 "%xmm1", "%xmm2", "%xmm3", @@ -580,15 +583,15 @@ { if (is_code(fnptr)) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("%d(%%esp)",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); + printf("%d(%%rsp)",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); } else - printf("%d(%%ebp)",CODE_LVAR(l)); + printf("%d(%%rbp)",CODE_LVAR(l)); } else if (l<0) { /* local variable */ - printf("%d(%%ebp)",FUNC_LVAR(l)); + printf("%d(%%rbp)",FUNC_LVAR(l)); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("%d(%%esp)",CALLER_ARG(l-ARG_LVAR_OFFSET)); + printf("%d(%%rsp)",CALLER_ARG(l-ARG_LVAR_OFFSET)); } else { /* callee's arguments */ - printf("%d(%%ebp)",CALLEE_ARG(l)); + printf("%d(%%rbp)",CALLEE_ARG(l)); } } @@ -599,7 +602,6 @@ use_int0() { int i = creg; if (!i||!ireg||!is_int_reg(i)) { - if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; } if (!ireg) { ireg = get_register(); } @@ -610,8 +612,8 @@ return i; } -#define is_data_reg(reg) (REG_EAX<=reg&®<=REG_EDX) -#define is_pointer_reg(reg) (REG_ESI<=reg&®<=REG_EBP) +#define is_data_reg(reg) (reg_name_l[reg]!=0) +#define is_pointer_reg(reg) (reg> REG_EBP) static int use_register(int reg0, int reg1, int move) @@ -623,9 +625,9 @@ char *move_op; code_clear_stack_reg(reg1); - move_op = (regs[reg1]||regs[reg1])?"\txchg %s,%s\n":"\tmovl %s,%s\n"; + move_op = (regs[reg1]||regs[reg1])?"\txchg %s,%s\n":"\tmovq %s,%s\n"; if (move && reg0!=reg1) { - printf(move_op,reg_name[reg0],reg_name[reg1]); + printf(move_op,reg_name_q[reg0],reg_name_q[reg1]); if (!regs[reg1]) regs[reg1]=USING_REG; } return reg0; @@ -661,14 +663,28 @@ if (!regs[i]) regs[i]=USING_REG; creg = ireg = i; if (ptreg && keep) { - printf("\tmovl %s,%s\n",reg_name[ptreg],reg_name[creg]); + printf("\tmovq %s,%s\n",reg_name_q[ptreg],reg_name_q[creg]); } return i; } +#define fregister_name(reg) reg_name_q[reg] + static void set_freg(int reg,int mode) { + if (!is_float_reg(reg)) error(-1); + if (reg!=creg) { + if (freg && reg!=freg) { + free_register(freg); + if (mode) { + printf("\tmovapd %s,%s\n",fregister_name(reg),fregister_name(freg)); + } + } + // if (creg!=ireg) free_register(creg); + regs[reg]=USING_REG; + } + creg = freg = reg; } static void @@ -683,7 +699,7 @@ if (ireg && reg!=ireg ) { if (regs[ireg]!=REG_VAR) free_register(ireg); if (mode) { - printf("\tmovl %s,%s\n",reg_name[ireg],reg_name[reg]); + printf("\tmovq %s,%s\n",reg_name_q[ireg],reg_name_q[reg]); } } if (creg>0 && regs[creg]!=REG_VAR) free_register(creg); @@ -693,29 +709,8 @@ if (!regs[reg]) regs[reg]=USING_REG; } -#define is_long_reg(reg) (reg==REG_LCREG||reg==REG_L) -#define use_longlong(reg) \ - if (reg==-1||is_long_reg(reg)) reg=use_longlong0(reg) - -static int -use_longlong0(int reg) -{ - int i = reg==USING_REG?creg:reg; - if (ireg) { if (regs[ireg]!=REG_VAR) free_register(ireg); ireg=0; } - if (!lreg||!regs[lreg]) { - // long long mode use all registers - code_save_stacks(); -#ifdef __APPLE__ - clear_ptr_cache(); -#endif - } - i = lreg = (reg==USE_CREG)?REG_LCREG:reg; - if (!regs[i]) regs[i]=USING_REG; - if (!regs[regv_l(i)]) regs[regv_l(i)]=USING_REG; - if (!regs[regv_h(i)]) regs[regv_h(i)]=USING_REG; - creg = lreg = i; - return i; -} +#define is_long_reg(reg) is_int_reg(reg) +#define use_longlong(reg) use_data_reg(reg) static void set_lreg(int reg,int mode) @@ -723,15 +718,6 @@ use_longlong(reg); } -char * -l_edx(int i) { - return i==REG_L?"%edi":"%edx"; -} -char * -l_eax(int i) { - return i==REG_L?"%esi":"%eax"; -} - extern void code_init(void) { @@ -750,11 +736,7 @@ struct_align = size_of_int; - // MAX_REGISTER=6; - MAX_DATA_REG=4; - MAX_POINTER=3; - MAX_REGISTER_VAR=2; - + MAX_DATA_REG=6; } @@ -774,14 +756,16 @@ { if (i<=0) { error(REG_ERR); - return "%eax"; + return "%rax"; } - if (byte==1 && i <= REG_EDX) { + if (byte==1 && is_data_reg(i)) { return reg_name_l[i]; - } else if (byte==SIZE_OF_SHORT && i <= REG_EDX) { + } else if (byte==SIZE_OF_SHORT && is_data_reg(i)) { return reg_name_w[i]; + } else if (byte==SIZE_OF_INT) { + return reg_name[i]; } else { - return reg_name[i]; /* 0 or 4 means int */ + return reg_name_q[i]; } } @@ -834,7 +818,7 @@ get_data_register(void) { /* 使われていないレジスタを調べる */ int i,reg,j; - for(i=REG_EAX;i<=REG_EDX;i++) { + for(i=1;is_data_reg(i) && i<MAX_REGISTER+1;i++) { if (! regs[i]) { /* 使われていないなら */ regs[i]=1; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ @@ -891,12 +875,10 @@ #ifdef __APPLE__ char *rrn = register_name(r,0); if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { - printf("\tleal _%s-_%d(%%ebx),%s\n",nptr->nm, - goffset_label,rrn); + printf("\tleaq _%s(%%rip),%s\n",nptr->nm, rrn); } else { - printf("\tmovl L_%s$non_lazy_ptr-_%d(%%ebx),%s\n", - nptr->nm, - goffset_label,rrn); + printf("\tmovq _%s@GOTPCREL(%%rip),%s\n", + nptr->nm, rrn); } #else error(-1); @@ -944,32 +926,46 @@ return 0; } +#if FLOAT_CODE int get_dregister(int d) -{ - return -1; -} - -int -get_lregister_var(NMTBL *n) -{ - int h,l; - h = REG_ESI; - l = REG_EDI; - if (regs[h]==0&®s[l]==0) { - regs[h]=regs[l]=REG_VAR; regs[REG_L]=REG_VAR; - reg_var=2; - return list2(LREGISTER,REG_L); +{ /* 使われていないレジスタを調べる */ + int i,reg; + for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { + if (regs[i]) continue; /* 使われている */ + regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + /* search register stack */ + for(i=0;i<freg_sp;i++) { + if ((reg=freg_stack[i])>=0) { + code_dassign_lvar( + (freg_stack[i]=new_lvar(SIZE_OF_DOUBLE)),reg,1); + freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; + return reg; + } } - return list3n(LVAR,new_lvar(SIZE_OF_LONGLONG),0); -} - -int -get_lregister() -{ - return -1; -} - + for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { + reg =FREG_VAR_BASE-i+FREG_OFFSET; + if (! regs[reg]) { /* 使われていないなら */ + regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ + if (i>max_freg_var) max_freg_var=i; + return reg; /* その場所を表す番号を返す */ + } + } + /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ + error(REG_ERR); return freg; +} + +int +pop_fregister(void) +{ /* レジスタから値を取り出す */ + return freg_stack[--freg_sp]; +} +#endif + +#define get_lregister_var(n) get_register_var(n) +#define get_lregister() get_register() int register_full(void) @@ -998,7 +994,7 @@ free_all_register(void) { int i; - for(i=1;i<MAX_REGISTER+REAL_MAX_LREGISTER+1;i++) { + for(i=1;i<REAL_MAX_REGISTER;i++) { regs[i]=0; } lreg = creg = ireg = 0; @@ -1009,14 +1005,8 @@ extern int code_register_overlap(int s,int t) { - if (car(s)==REGISTER) { - if (car(t)==REGISTER) return cadr(s)==cadr(t); - if (car(t)==LREGISTER) - return cadr(s)==REG_ESI|| cadr(s)==REG_EDI; - } else if (car(s)==LREGISTER) { - if (car(t)==LREGISTER) return 1; - if (car(t)==REGISTER) - return cadr(t)==REG_ESI|| cadr(t)==REG_EDI; + if (car(s)==REGISTER||car(s)==LREGISTER) { + if (car(t)==REGISTER||car(t)==LREGISTER) return cadr(s)==cadr(t); } return 0; } @@ -1037,6 +1027,9 @@ printf(" %s",register_name(reg_stack[i],0)); } #endif + for(i=RET_FREGISTER;i<REAL_MAX_REGISTER;i++) { + printf("%d",regs[i]); + } printf("## f:%d",freg_sp); printf("\n"); } @@ -1060,14 +1053,15 @@ // n->dsp = offset; // printf("### %s %d %d\n",n->nm,n->dsp,n->ty); if (scalar(type)) { + int sz =size(type)<=SIZE_OF_INT?SIZE_OF_INT:size(type); if ((reg = get_input_register_var(reg_var,n,is_code0))) { n->sc = REGISTER; n->dsp = cadr(reg); regs[n->dsp]= INPUT_REG; reg_var++; - caddr(args)=SIZE_OF_INT; /* why we need this? */ + caddr(args)=sz; } - offset+=SIZE_OF_INT; + offset+=sz; } else if (type==FLOAT||type==DOUBLE) { if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { n->sc = DREGISTER; @@ -1127,11 +1121,14 @@ get_register_var(NMTBL *nptr) { int i; - for(i=REG_ESI;i<REG_EBP;i++) { - if (! regs[i]) { /* 使われていないなら */ - regs[i]=REG_VAR; /* そのレジスタを使うことを宣言し */ - return list3n(REGISTER,i,nptr); /* その場所を表す番号を返す */ - } + for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { + if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ + /* そのレジスタを使うことを宣言し */ + regs[REG_VAR_BASE-i]=REG_VAR; + if (i>max_reg_var) max_reg_var=i; + /* その場所を表す番号を返す */ + return list3n(REGISTER,REG_VAR_BASE-i,n); + } } return list3n(LVAR,new_lvar(SIZE_OF_INT),0); } @@ -1139,7 +1136,17 @@ int get_dregister_var(NMTBL *nptr,int d) { - return list3n(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT),0); + int i; + for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { + if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ + regs[FREG_VAR_BASE-i+FREG_OFFSET]=REG_VAR; /*そのレジスタを使うことを宣言し*/ + if (i>max_freg_var) max_freg_var=i; + /* その場所を表す番号を返す */ + return list3n(DREGISTER, + FREG_VAR_BASE-i+FREG_OFFSET,n); + } + } + return list3n(LVAR,new_lvar(SIZE_OF_DOUBLE),0); } @@ -1184,19 +1191,24 @@ code_gvar(int e1,int creg) { use_int(creg); #ifdef __APPLE__ - int r = get_ptr_cache(ncaddr(e1)); + NMTBL nptr = ncaddr(e1); + if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { + printf("\tleaq _%s+%d(%%rip),%s\n", ntpr->nm,cadr(e1),register_name(creg,0)); + return; + } + int r = get_ptr_cache(ntpr); if (cadr(e1)) { - printf("\tleal %d(%s),%s\n", cadr(e1),register_name(r,0), + printf("\tleaq %d(%s),%s\n", cadr(e1),register_name(r,0), register_name(creg,0)); } else { - printf("\tmovl %s,%s\n", register_name(r,0), register_name(creg,0)); + printf("\tmovq %s,%s\n", register_name(r,0), register_name(creg,0)); } #else if (cadr(e1)) { - printf("\tmovl $%s+%d,%s\n",(ncaddr(e1))->nm,cadr(e1), + printf("\tmovq $%s+%d,%s\n",nptr->nm,cadr(e1), register_name(creg,0)); } else { - printf("\tmovl $%s,%s\n",(ncaddr(e1))->nm,register_name(creg,0)); + printf("\tmovq $%s,%s\n",nptr->nm,register_name(creg,0)); } #endif @@ -1206,19 +1218,24 @@ code_rgvar(int e1,int creg) { use_int(creg); #ifdef __APPLE__ + NMTBL nptr = ncaddr(e1); + if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { + printf("\tmovl _%s+%d(%%rip),%s\n", ntpr->nm,cadr(e1),register_name(creg,SIZE_OF_INT)); + return; + } int r = get_ptr_cache(ncaddr(e1)); if (cadr(e1)) { printf("\tmovl %d(%s),%s\n", cadr(e1),register_name(r,0), register_name(creg,0)); } else { - printf("\tmovl (%s),%s\n", register_name(r,0), register_name(creg,0)); + printf("\tmovl (%s),%s\n", register_name(r,0), register_name(creg,SIZE_OF_INT)); } #else if (cadr(e1)) { - printf("\tmovl %s+%d,%s\n",(ncaddr(e1))->nm,cadr(e1), - register_name(creg,0)); + printf("\tmovl %s+%d,%s\n",nptr->nm,cadr(e1), + register_name(creg,SIZE_OF_INT)); } else - printf("\tmovl %s,%s\n",(ncaddr(e1))->nm,register_name(creg,0)); + printf("\tmovl %s,%s\n",nptr->nm,register_name(creg,SIZE_OF_INT)); #endif } @@ -1233,21 +1250,26 @@ code_crgvar(int e1,int creg,int sign,int sz){ use_int(creg); #ifdef __APPLE__ + NMTBL nptr = ncaddr(e1); + if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { + printf("\t%s _%s+%d(%%rip),%s\n", cload(sign,sz),ntpr->nm,cadr(e1),register_name(creg,SIZE_OF_INT)); + return; + } int r = get_ptr_cache(ncaddr(e1)); if (cadr(e1)) { printf("\t%s %d(%s),%s\n", cload(sign,sz),cadr(e1),register_name(r,0), - register_name(creg,0)); + register_name(creg,SIZE_OF_INT)); } else { printf("\t%s (%s),%s\n", cload(sign,sz), - register_name(r,0), register_name(creg,0)); + register_name(r,0), register_name(creg,SIZE_OF_INT)); } #else if (cadr(e1)) { printf("\t%s %s+%d,%s\n",cload(sign,sz), - (ncaddr(e1))->nm,cadr(e1),register_name(creg,0)); + nptr->nm,cadr(e1),register_name(creg,SIZE_OF_INT)); } else printf("\t%s %s,%s\n",cload(sign,sz), - (ncaddr(e1))->nm,register_name(creg,0)); + nptr->nm,register_name(creg,SIZE_OF_INT)); #endif } @@ -1256,7 +1278,7 @@ void code_lvar(int e2,int creg) { use_int(creg); - printf("\tlea "); lvar(e2); + printf("\tleaq "); lvar(e2); printf(",%s\n",register_name(creg,0)); } @@ -1265,7 +1287,7 @@ code_register(int e2,int creg) { use_int(creg); if (e2!=creg) - printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0)); + printf("\tmovq %s,%s\n",register_name(e2,0),register_name(creg,0)); } @@ -1273,7 +1295,7 @@ code_rlvar(int e2,int reg) { use_int(reg); printf("\tmovl "); lvar(e2); - printf(",%s\n",register_name(reg,0)); + printf(",%s\n",register_name(reg,SIZE_OF_INT)); } extern void @@ -1281,7 +1303,7 @@ { use_data_reg(reg,1); printf("\t%s %s,%s\n",cload(1,1), - register_name(reg,1),register_name(reg,0)); + register_name(reg,1),register_name(reg,SIZE_OF_INT)); } extern void @@ -1289,7 +1311,7 @@ { use_data_reg(reg,1); printf("\t%s %s,%s\n",cload(1,SIZE_OF_SHORT), - register_name(reg,2),register_name(reg,0)); + register_name(reg,2),register_name(reg,SIZE_OF_INT)); } extern void @@ -1297,7 +1319,7 @@ { use_data_reg(reg,1); printf("\t%s %s,%s\n",cload(0,1), - register_name(reg,1),register_name(reg,0)); + register_name(reg,1),register_name(reg,SIZE_OF_INT)); } extern void @@ -1305,14 +1327,14 @@ { use_data_reg(reg,1); printf("\t%s %s,%s\n",cload(0,SIZE_OF_SHORT), - register_name(reg,2),register_name(reg,0)); + register_name(reg,2),register_name(reg,SIZE_OF_INT)); } void code_crlvar(int e2,int reg,int sign,int sz) { use_int(reg); printf("\t%s ",cload(sign,sz)); lvar(e2); - printf(",%s\n",register_name(reg,0)); + printf(",%s\n",register_name(reg,SIZE_OF_INT)); } @@ -1322,14 +1344,14 @@ use_int(creg); #ifdef __APPLE__ if (n->sc==STATIC) { - printf("\tleal _%s-_%d(%%ebx),%s\n", n->nm, goffset_label, + printf("\tleaq _%s(%%rip),%s\n", n->nm, register_name(creg,0)); return; } int r = get_ptr_cache(n); - printf("\tmovl %s,%s\n", register_name(r,0), register_name(creg,0)); + printf("\tmovq %s,%s\n", register_name(r,0), register_name(creg,0)); #else - printf("\tmovl $%s,%s\n",n->nm,register_name(creg,0)); + printf("\tmovq $%s,%s\n",n->nm,register_name(creg,0)); #endif } @@ -1337,30 +1359,30 @@ code_label_value(int label,int reg) { use_int(reg); #ifdef __APPLE__ - printf("\tleal _%d-_%d(%%ebx),%s\n", - label,goffset_label,register_name(reg,0)); + printf("\tleaq _%d(%%rip),%s\n", + label,register_name(reg,0)); #else - printf("\tleal _%d,%s\n",label,register_name(reg,0)); + printf("\tleaq _%d,%s\n",label,register_name(reg,0)); #endif } void code_const(int e2,int creg) { use_int(creg); - printf("\tmovl $%d,%s\n",e2,register_name(creg,0)); + printf("\tmovl $%d,%s\n",e2,register_name(creg,SIZE_OF_INT)); } void code_neg(int creg) { use_int(creg); - printf("\tnegl %s\n", register_name(creg,0)); + printf("\tnegl %s\n", register_name(creg,SIZE_OF_INT)); } void code_not(int creg) { use_int(creg); - printf("\tnotl %s\n", register_name(creg,0)); + printf("\tnotl %s\n", register_name(creg,SIZE_OF_INT)); } @@ -1370,9 +1392,9 @@ use_data_reg(creg,1); xrn = register_name(creg,1); - printf("\tcmpl $0,%s\n", register_name(creg,0)); + printf("\tcmpl $0,%s\n", register_name(creg,SIZE_OF_INT)); printf("\tsete %s\n", xrn); - printf("\tmovzbl %s,%s\n", xrn,register_name(creg,0)); + printf("\tmovzbl %s,%s\n", xrn,register_name(creg,SIZE_OF_INT)); } void @@ -1380,9 +1402,9 @@ char *xrn; if (car(e2)==REGISTER) { use_int(reg); - printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),0)); + printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),SIZE_OF_INT)); if (use) - printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0)); + printf("\tmovl %s,%s\n",register_name(cadr(e2),SIZE_OF_INT),register_name(reg,SIZE_OF_INT)); return; } g_expr(e2); @@ -1400,8 +1422,8 @@ if (car(e2)==REGISTER) { use_int(reg); if (use) - printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0)); - printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),0)); + printf("\tmovl %s,%s\n",register_name(cadr(e2),SIZE_OF_INT),register_name(reg,SIZE_OF_INT)); + printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),SIZE_OF_INT)); return; } @@ -1410,7 +1432,7 @@ xrn = register_name((e2=emit_pop(0)),0); use_int(reg); if (use) - printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,0)); + printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,SIZE_OF_INT)); printf("\t%s $%d,(%s)\n",(sz==1)?"addb":(sz==SIZE_OF_SHORT)?"addw":"addl",dir,xrn); emit_pop_free(e2); } @@ -1420,14 +1442,18 @@ void code_return(int creg) { use_int(creg); - printf("\tleal _%d,%s\n",retcont,register_name(creg,0)); +#ifdef __APPLE__ + printf("\tleaq _%d(%%rip),%s\n",retcont,register_name(creg,0)); +#else + printf("\tleaq _%d,%s\n",retcont,register_name(creg,0)); +#endif } void code_environment(int creg) { use_int(creg); - printf("\tmovl %%ebp,%s\n",register_name(creg,0)); + printf("\tmovq %%rbp,%s\n",register_name(creg,0)); } static int rexpr_bool(int e1,int reg); @@ -1447,7 +1473,7 @@ if (use) { use_int(reg); xrn = register_name(reg,0); - printf("\txorl %s,%s\n",xrn,xrn); + printf("\txorq %s,%s\n",xrn,xrn); jmp(e3=fwdlabel()); fwddef(e2); printf("\tmovl $1,%s\n",xrn); @@ -1557,7 +1583,7 @@ void code_cmp_register(int e2,int label,int cond) { use_int(e2); - printf("\tcmpl $0,%s\n",register_name(e2,0)); + printf("\tcmpl $0,%s\n",register_name(e2,SIZE_OF_INT)); jcond(label,cond); } @@ -1583,11 +1609,10 @@ text_mode(0); } #ifdef __APPLE__ - printf("\tleal _%d-_%d(%%ebx),%s\n",lb, - goffset_label, + printf("\tleaq _%d(%%rip),%s\n",lb, register_name(creg,0)); #else - printf("\tlea _%d,%s\n",lb,register_name(creg,0)); + printf("\tleaq _%d,%s\n",lb,register_name(creg,0)); #endif set_attr(n,LABEL,lb); } @@ -1624,14 +1649,22 @@ free_register(dreg); break; case 4: case -4: - drn = register_name(dreg = get_register(),0); + drn = register_name(dreg = get_register(),SIZE_OF_INT); printf("\tmovl %d(%s),%s\n",offset,frn,drn); printf("\tmovl %s,%d(%s)\n",drn,offset,trn); free_register(dreg); break; + case 8: case -8: + drn = register_name(dreg = get_register(),0); + printf("\tmovq %d(%s),%s\n",offset,frn,drn); + printf("\tmovq %s,%d(%s)\n",drn,offset,trn); + free_register(dreg); + break; default: if (length <0) { if (length > -MAX_COPY_LEN) { + for(;length<=-8;length+=8,offset-=8) + emit_copy(from,to,-8,offset-8,0,det); for(;length<=-4;length+=4,offset-=4) emit_copy(from,to,-4,offset-4,0,det); for(;length<=-2;length+=2,offset-=2) @@ -1641,6 +1674,8 @@ break; } } else if (length <=MAX_COPY_LEN) { + for(;length>=8;length-=8,offset+=8) + emit_copy(from,to,8,offset,0,det); for(;length>=4;length-=4,offset+=4) emit_copy(from,to,4,offset,0,det); for(;length>=2;length-=2,offset+=2) @@ -1653,36 +1688,36 @@ // clear_ptr_cache(); // code_save_stacks(); - printf("\tpushl %%esi\n"); - printf("\tpushl %%edi\n"); - printf("\tpushl %%ecx\n"); - printf("\tpushl %s\n",register_name(from,0)); - printf("\tpushl %s\n",register_name(to,0)); + printf("\tpushq %%rsi\n"); + printf("\tpushq %%rdi\n"); + printf("\tpushq %%rcx\n"); + printf("\tpushq %s\n",register_name(from,0)); + printf("\tpushq %s\n",register_name(to,0)); printf("\tpopl %%edi\n"); printf("\tpopl %%esi\n"); if (length<0) { - printf("\tmovl $%d,%%ecx\n",-length/4); - printf("\taddl $%d,%%esi\n",-length-4); - printf("\taddl $%d,%%edi\n",-length-4 - +(to==REG_ESP?4*4:0) + printf("\tmovq $%d,%%rcx\n",-length/4); + printf("\taddq $%d,%%rsi\n",-length-4); + printf("\taddq $%d,%%rdi\n",-length-4 + +(to==REG_ESP?8*8:0) ); printf("\tstd\n\trep\n\tmovsl\n"); - printf("\tpopl %%ecx\n"); - printf("\tpopl %%edi\n"); - printf("\tpopl %%esi\n"); + printf("\tpopq %%rcx\n"); + printf("\tpopq %%rdi\n"); + printf("\tpopq %%rsi\n"); if(length%4) { offset = offset+length/SIZE_OF_INT; length=length%4; emit_copy(from,to,length,offset,0,det); } } else { - printf("\tmovl $%d,%%ecx\n",length/4); + printf("\tmovq $%d,%%rcx\n",length/4); if (to==REG_ESP) - printf("\taddl $%d,%%edi\n",4*4); + printf("\taddl $%d,%%rdi\n",8*4); printf("\tcld\n\trep\n\tmovsl\n"); - printf("\tpopl %%ecx\n"); - printf("\tpopl %%edi\n"); - printf("\tpopl %%esi\n"); + printf("\tpopq %%rcx\n"); + printf("\tpopq %%rdi\n"); + printf("\tpopq %%rsi\n"); if(length%4) { offset = offset+length/SIZE_OF_INT; length=length%4; @@ -1761,19 +1796,25 @@ return reg_arg_list; } - static void increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { int nargs=0,reg_arg=0,freg_arg=0; - int t=caddr(e3); + int t=type_value(caddr(e3)); + if (t>=0&&(car(t)==BIT_FIELD)) { + t = type_value(cadr(t)); + } if(scalar(t)) { - nargs ++ ; reg_arg++; freg_arg++; - } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) { nargs ++ ; reg_arg++; + if (size(t)>SIZE_OF_INT) nargs++; + } else if (t==LONGLONG||t==ULONGLONG) { + nargs ++ ; nargs ++ ; reg_arg++; } else if (t==FLOAT) { - reg_arg ++ ; freg_arg++; + freg_arg++; nargs += size(t)/SIZE_OF_INT; + } else if (t==DOUBLE) { + nargs += size(t)/SIZE_OF_INT; + freg_arg++; } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { nargs += round4(size(t))/SIZE_OF_INT; } else { @@ -1785,6 +1826,7 @@ *pfreg_arg += freg_arg; } + #define AS_SAVE 1 #define AS_ARG 0 @@ -1838,11 +1880,7 @@ code_call(int e2,NMTBL *fn,int jmp) { if (car(e2) == FNAME) { -#ifdef __APPLE__ - printf("\tcall\tL_%s$stub\n",fn->nm); -#else - printf("\tcall\t%s\n",fn->nm); -#endif + printf("\tcall\t_%s\n",fn->nm); } else { printf("\tcall\t*%s\n",register_name(REG_EAX,0)); } @@ -1926,10 +1964,10 @@ arg = get_register_var(0); #if ARG_ORDER==1 delayed_arg = list2( - assign_expr0(arg,e4,INT,INT), + assign_expr0(arg,e4,LONGLONG,LONGLONG), delayed_arg); #else - g_expr_u(assign_expr0(arg,e4,INT,INT)); + g_expr_u(assign_expr0(arg,e4,LONGLONG,LONGLONG)); #endif car(e3)=arg; reg_arg_list = list2(arg,reg_arg_list); @@ -2051,16 +2089,16 @@ code_const(round16(cadr(e1)),reg); } crn = register_name(reg,0); - printf("\tsubl\t%s, %%esp\n",crn); + printf("\tsubq\t%s, %%rsp\n",crn); if (!max_func_arg_label) max_func_arg_label = fwdlabel(); - printf("\tmovl $%s%d,%s\n",lpfx,max_func_arg_label ,crn); - printf("\tadd\t%%esp, %s\n",crn); + printf("\tmovq $%s%d,%s\n",lpfx,max_func_arg_label ,crn); + printf("\taddq\t%%rsp, %s\n",crn); } void code_frame_pointer(int e3) { use_int(e3); - printf("\tmovl %s,%%ebp\n",register_name(e3,0)); + printf("\tmovq %s,%%rbp\n",register_name(e3,0)); } int @@ -2076,11 +2114,7 @@ void code_jmp(char *s) { -#ifdef __APPLE__ - printf("\tjmp\tL_%s$stub\n",s); -#else - printf("\tjmp %s\n",s); -#endif + printf("\tjmp _%s\n",s); } @@ -2098,7 +2132,7 @@ op=cload(sign,byte); crn = register_name(creg,0); use_int(reg); - printf("\t%s %d(%s),%s\n",op,offset,crn,register_name(reg,0)); + printf("\t%s %d(%s),%s\n",op,offset,crn,register_name(reg,SIZE_OF_INT)); } #if FLOAT_CODE @@ -2106,7 +2140,7 @@ code_drindirect(int e1, int reg,int offset, int d) { g_expr(e1); - printf("\t%s %d(%s)\n",fload(d),offset,register_name(creg,0)); + printf("\t%s %d(%s),%s\n",fload(d),offset,register_name(creg,0),register_name(reg,0)); return DOUBLE; } #endif @@ -2118,13 +2152,7 @@ { char *crn = register_name(creg,0); use_longlong(reg); - if((reg==REG_L&&creg==REG_ESI)||(creg==REG_EAX)) { - printf("\tmovl %d(%s),%s\n",offset+SIZE_OF_INT,crn,l_edx(reg)); - printf("\tmovl %d(%s),%s\n",offset,crn,l_eax(reg)); - } else { - printf("\tmovl %d(%s),%s\n",offset,crn,l_eax(reg)); - printf("\tmovl %d(%s),%s\n",offset+SIZE_OF_INT,crn,l_edx(reg)); - } + printf("\tmovq %d(%s),%s\n",offset,crn,register_name(reg,0)); } int @@ -2142,7 +2170,8 @@ char * move(int byte) { - return byte==1?"movb":byte==SIZE_OF_SHORT?"movw":"movl"; + return byte==1?"movb":byte==SIZE_OF_SHORT?"movw": + byte==SIZE_OF_INT?"movl":"movq"; } void @@ -2177,7 +2206,7 @@ code_assign_register(int e2,int byte,int creg) { use_int(creg); if (creg!=e2) - printf("\tmovl %s,%s\n",register_name(creg,0),register_name(e2,0)); + printf("\tmovq %s,%s\n",register_name(creg,0),register_name(e2,0)); } void @@ -2261,8 +2290,8 @@ return; } // regs[oreg]=1; - orn = register_name(oreg,0); - crn = register_name(reg,0); + orn = register_name(oreg,SIZE_OF_INT); + crn = register_name(reg,SIZE_OF_INT); switch(op) { case ADD: printf("\taddl %s,%s\n",orn,crn); @@ -2326,7 +2355,7 @@ char *crn; int datareg; use_int(reg); - crn = register_name(reg,0); + crn = register_name(reg,SIZE_OF_INT); orn = cadr(orn); datareg=is_data_reg(reg); @@ -2389,7 +2418,7 @@ int dreg; use_register(oreg,REG_ECX,1); dreg = (reg==REG_ECX)?oreg:reg; - printf("\t%s %%cl,%s\n",op,register_name(dreg,0)); + printf("\t%s %%cl,%s\n",op,register_name(dreg,SIZE_OF_INT)); set_ireg(dreg,0); set_ireg(reg,1); } @@ -2404,10 +2433,10 @@ } if (n) printf("\t%s %d(%s),%s\n",cload(sign,byte),n, - register_name(xreg,0),register_name(reg,0)); + register_name(xreg,0),register_name(reg,SIZE_OF_INT)); else printf("\t%s (%s),%s\n",cload(sign,byte), - register_name(xreg,0),register_name(reg,0)); + register_name(xreg,0),register_name(reg,SIZE_OF_INT)); } int @@ -2467,7 +2496,7 @@ g_expr(list3(CMP,cadr(e1),caddr(e1))); use_data_reg(reg,1); printf("\tset%s\t%s\n",s,register_name(reg,1)); - printf("\tmovzbl %s,%s\n",register_name(reg,1),register_name(reg,0)); + printf("\tmovzbl %s,%s\n",register_name(reg,1),register_name(reg,SIZE_OF_INT)); return 1; } @@ -2528,16 +2557,9 @@ code_enter1(int args) { code_disp_label=fwdlabel(); - printf("\tlea -_%d(%%ebp),%%esp\n",code_disp_label); + printf("\tlea -_%d(%%rbp),%%rsp\n",code_disp_label); // printf("## args %d disp %d code_disp_offset=%d\n",args,disp,code_disp_offset); -#ifdef __APPLE__ - printf("\tcall\t___i686.get_pc_thunk.bx\n"); - printf("_%d:\n",labelno); - goffset_label = labelno; - labelno++; - regs[REG_EBX] = 1; -#endif } void @@ -2575,18 +2597,11 @@ r1_offset_label = fwdlabel(); max_func_args = 0; - printf("\tpushl %%ebp\n"); - printf("\tmovl %%esp,%%ebp\n"); - printf("\tpushl %%ebx\n"); - printf("\tpushl %%esi\n"); - printf("\tpushl %%edi\n"); + printf("\tpushq %%rbp\n"); + printf("\tmovq %%rsp,%%rbp\n"); + printf("\tpushq %%rbx\n"); printf("\tlea -%s%d(%%ebp),%%esp\n",lpfx,r1_offset_label); #ifdef __APPLE__ - printf("\tcall\t___i686.get_pc_thunk.bx\n"); - printf("_%d:\n",labelno); - goffset_label = labelno; - labelno++; - regs[REG_EBX] = 1; clear_ptr_cache(); #endif @@ -2618,20 +2633,20 @@ int ty = cadr(fnptr->ty); fwddef(retcont); if (ty==FLOAT||ty==DOUBLE) { - printf("\tfldl %d(%%ebp)\n",-SIZE_OF_DOUBLE); - printf("\tmovl %s,%%ebp\n",reg_name[REG_ESI]); + printf("\tmovsd %d(%%rbp),%s\n",-SIZE_OF_DOUBLE,register_name(creg,0)); + printf("\tmovq %s,%%rbp\n",reg_name_l[REG_ESI]); } else if (ty==LONGLONG||ty==ULONGLONG) { set_lreg(RET_LREGISTER,0); - printf("\tmovl %d(%%ebp),%%ebp\n",disp-SIZE_OF_INT); + printf("\tmovq %d(%%rbp),%%rbp\n",disp-SIZE_OF_LONGLONG); } else if (ty>0&&( car(ty)==STRUCT || car(ty)==UNION)) { set_ireg(RET_REGISTER,0); - printf("\tmovl %d(%%ebp),%s\n",disp-SIZE_OF_INT, + printf("\tmovq %d(%%rbp),%s\n",disp-SIZE_OF_LONGLONG, register_name(creg,0)); - printf("\tmovl %s,%%ebp\n",reg_name[REG_EDI]); + printf("\tmovq %s,%%rbp\n",reg_name_l[REG_EDI]); } else if (ty!=VOID) { set_ireg(RET_REGISTER,0); - printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0)); - printf("\tmovl %s,%%ebp\n",reg_name[REG_EDI]); + printf("\tmovq %s,%s\n",reg_name_l[REG_ESI],register_name(creg,0)); + printf("\tmovq %s,%%rbp\n",reg_name_l[REG_EDI]); } } @@ -2656,9 +2671,7 @@ code_offset_set(fnptr); printf("\tlea %d(%%ebp),%%esp\n",-12); - printf("\tpopl %%edi\n"); - printf("\tpopl %%esi\n"); - printf("\tpopl %%ebx\n"); + printf("\tpopq %%rbx\n"); <--- register save printf("\tleave\n"); printf("\tret\n"); #ifndef __APPLE__ @@ -2702,10 +2715,10 @@ code_set_return_register(int mode) { // before goto leave code, set return register if (cadr(fnptr->ty)==FLOAT) { - // set_freg(RET_FREGISTER,mode); + set_freg(RET_FREGISTER,mode); return 0; } else if (cadr(fnptr->ty)==DOUBLE) { - // set_dreg(RET_DREGISTER,mode); + set_dreg(RET_DREGISTER,mode); return 0; } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) { set_lreg(RET_LREGISTER,mode); @@ -2847,11 +2860,7 @@ #if LONGLONG_CODE long long ll = lcadr(e); data_mode(0); -#if (ENDIAN_L==0) - printf("\t.long\t0x%x,0x%x\n",code_l1(ll),code_l2(ll)); -#else - printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll)); -#endif + printf("\t.quad\t0x%llx\n",ll); #endif } @@ -3088,24 +3097,9 @@ char * -fstore(int d) -{ - return use? - (d?"fstl":"fsts"): - (d?"fstpl":"fstps") - ; -} - -char * -fstore_u(int d) -{ - return d?"fstpl":"fstps"; -} - -char * fload(int d) { - return d?"fldl":"flds"; + return d?"movsd":"movss"; }
--- a/mc-code-ia32.c Thu Nov 04 21:10:20 2010 +0900 +++ b/mc-code-ia32.c Thu Nov 04 23:18:42 2010 +0900 @@ -1358,9 +1358,14 @@ void code_return(int creg) { use_int(creg); +#ifdef __APPLE__ + // printf("\tleal _%d(%%rip),%s\n",retcont,register_name(creg,0)); + printf("\tleal _%d-_%d(%%ebx),%s\n", + retcont,goffset_label,register_name(reg,0)); +#else printf("\tleal _%d,%s\n",retcont,register_name(creg,0)); -} - +#endif +} void code_environment(int creg) {