20
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
28
/* number of available registers */
26
35
/* a register can belong to several classes. The classes must be
27
36
sorted from more general to more precise (see gv2() code which does
64
85
/* f1 */ RC_FLOAT | RC_F1,
65
86
/* f2 */ RC_FLOAT | RC_F2,
66
87
/* f3 */ RC_FLOAT | RC_F3,
89
/* d4/s8 */ RC_FLOAT | RC_F4,
90
/* d5/s10 */ RC_FLOAT | RC_F5,
91
/* d6/s12 */ RC_FLOAT | RC_F6,
92
/* d7/s14 */ RC_FLOAT | RC_F7,
69
96
static int two2mask(int a,int b) {
74
101
return reg_classes[r]&~(RC_INT|RC_FLOAT);
105
#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
77
108
/* return registers for function */
78
109
#define REG_IRET TREG_R0 /* single word int return register */
79
110
#define REG_LRET TREG_R1 /* second word return register (for long long) */
86
117
are directly pushed on stack. */
87
118
//#define FUNC_STRUCT_PARAM_AS_PTR
120
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
121
static CType float_type, double_type, func_float_type, func_double_type;
89
124
/* pointer size, in bytes */
90
125
#define PTR_SIZE 4
92
127
/* long double size and alignment, in bytes */
93
#define LDOUBLE_SIZE 8
129
#define LDOUBLE_SIZE 8
133
#define LDOUBLE_SIZE 8
137
#define LDOUBLE_ALIGN 8
94
139
#define LDOUBLE_ALIGN 4
95
142
/* maximum alignment (for aligned attribute support) */
96
143
#define MAX_ALIGN 8
287
335
gsym_addr(t, ind);
339
static unsigned long vfpr(int r)
341
if(r<TREG_F0 || r>TREG_F7)
342
error("compiler error! register %i is no vfp register",r);
290
346
static unsigned long fpr(int r)
292
348
if(r<TREG_F0 || r>TREG_F3)
293
error("compiler error! register %i is no fp register\n",r);
349
error("compiler error! register %i is no fpa register",r);
297
354
static unsigned long intr(int r)
301
358
if((r<0 || r>4) && r!=14)
302
error("compiler error! register %i is no int register\n",r);
359
error("compiler error! register %i is no int register",r);
395
return 0x30000000; /* CC/LO */
397
return 0x20000000; /* CS/HS */
399
return 0x00000000; /* EQ */
401
return 0x10000000; /* NE */
403
return 0x90000000; /* LS */
405
return 0x80000000; /* HI */
407
return 0x40000000; /* MI */
409
return 0x50000000; /* PL */
411
return 0xB0000000; /* LT */
413
return 0xA0000000; /* GE */
415
return 0xD0000000; /* LE */
417
return 0xC0000000; /* GT */
358
419
error("unexpected condition code");
420
return 0xE0000000; /* AL */
362
423
static int negcc(int cc)
432
497
if(v == VT_LOCAL) {
433
498
if(is_float(ft)) {
434
499
calcaddr(&base,&fc,&sign,1020,2);
501
op=0xED100A00; /* flds */
504
if ((ft & VT_BTYPE) != VT_FLOAT)
505
op|=0x100; /* flds -> fldd */
506
o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
447
520
o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
448
} else if((ft & VT_TYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_SHORT) {
522
} else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
523
|| (ft & VT_BTYPE) == VT_SHORT) {
449
524
calcaddr(&base,&fc,&sign,255,0);
451
526
if ((ft & VT_BTYPE) == VT_SHORT)
550
629
if(v == VT_LOCAL) {
551
630
if(is_float(ft)) {
552
631
calcaddr(&base,&fc,&sign,1020,2);
633
op=0xED000A00; /* fsts */
636
if ((ft & VT_BTYPE) != VT_FLOAT)
637
op|=0x100; /* fsts -> fstd */
638
o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
635
723
r = vtop->r & VT_VALMASK;
636
724
if (r == VT_CMP || (r & ~1) == VT_JMP)
727
if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT
728
&& type_size(&vtop[-nb_args].type, &align) <= 4) {
731
vtop[-nb_args]=vtop[-nb_args+1];
732
vtop[-nb_args+1]=tmp;
737
vtop->type.t = VT_LLONG;
739
for(i = nb_args + 1 ; i-- ;) {
740
size = type_size(&vtop[-i].type, &align);
741
if(args_size & (align-1)) {
743
vtop->type.t = VT_VOID; /* padding */
748
args_size += (size + 3) & -4;
639
753
for(i = nb_args ; i-- && args_size < 16 ;) {
640
if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) {
754
switch(vtop[-i].type.t & VT_BTYPE) {
641
759
size = type_size(&vtop[-i].type, &align);
642
size = (size + 3) & ~3;
760
size = (size + 3) & -4;
643
761
args_size += size;
644
} else if ((vtop[-i].type.t & VT_BTYPE) == VT_FLOAT)
646
else if ((vtop[-i].type.t & VT_BTYPE) == VT_DOUBLE)
648
else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE)
649
args_size += LDOUBLE_SIZE;
651
764
plan[nb_args-1-i][0]=args_size/4;
653
766
if ((vtop[-i].type.t & VT_BTYPE) == VT_LLONG && args_size < 16) {
662
775
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
663
776
size = type_size(&vtop->type, &align);
664
777
/* align to stack align size */
665
size = (size + 3) & ~3;
778
size = (size + 3) & -4;
666
779
/* allocate the necessary size on stack */
668
781
/* generate structure store */
718
842
s=regmask(plan[nb_args-i-1][0]);
719
843
todo&=~(1<<plan[nb_args-i-1][0]);
846
if(vtop->type.t == VT_VOID) {
848
o(0xE24DD004); /* sub sp,sp,#4 */
723
854
o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
760
891
gadd_sp(args_size);
893
if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT
894
&& type_size(&vtop->type.ref->type, &align) <= 4)
896
store(REG_IRET,vtop-keep);
900
else if(is_float(vtop->type.ref->type.t)) {
901
if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
902
o(0xEE000A10); /* fmsr s0,r0 */
904
o(0xEE000B10); /* fmdlr d0,r0 */
905
o(0xEE201B10); /* fmdhr d0,r1 */
764
914
/* generate function prolog of type 't' */
770
920
sym = func_type->ref;
771
921
func_vt = sym->type;
775
if((func_vt.t & VT_BTYPE) == VT_STRUCT) {
925
if((func_vt.t & VT_BTYPE) == VT_STRUCT
926
&& type_size(&func_vt,&align) > 4)
780
932
for(sym2=sym->next;sym2 && n<4;sym2=sym2->next) {
781
933
size = type_size(&sym2->type, &align);
782
size = (size + 3) & ~3;
785
936
o(0xE1A0C00D); /* mov ip,sp */
786
937
if(func_type->ref->c == FUNC_ELLIPSIS)
791
945
o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
793
o(0xE92D5800); /* save fp, ip, lr*/
794
o(0xE1A0B00D); /* mov fp,sp */
947
o(0xE92D5800); /* save fp, ip, lr */
948
o(0xE28DB00C); /* add fp, sp, #12 */
795
949
func_sub_sp_offset = ind;
796
950
o(0xE1A00000); /* nop, leave space for stack adjustment */
797
951
while ((sym = sym->next)) {
799
953
type = &sym->type;
954
size = type_size(type, &align);
955
size = (size + 3) & -4;
957
addr = (addr + align - 1) & -align;
800
959
sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
801
size = type_size(type, &align);
802
size = (size + 3) & ~3;
805
962
last_itod_magic=0;
809
967
/* generate function epilog */
810
968
void gfunc_epilog(void)
813
o(0xE89BA800); /* restore fp, sp, pc */
815
x=stuff_const(0xE24DD000, (-loc + 3) & -4); /* sub sp,sp,# */
973
if(is_float(func_vt.t)) {
974
if((func_vt.t & VT_BTYPE) == VT_FLOAT)
975
o(0xEE100A10); /* fmrs r0, s0 */
977
o(0xEE100B10); /* fmrdl r0, d0 */
978
o(0xEE301B10); /* fmrdh r1, d0 */
982
o(0xE91BA800); /* restore fp, sp, pc */
983
diff = (-loc + 3) & -4;
986
diff = (diff + 7) & -8;
989
x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
817
991
*(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = x;
819
993
unsigned long addr;
821
995
o(0xE59FC004); /* ldr ip,[pc+4] */
822
o(0xE04DD00C); /* sub sp,sp,ip */
996
o(0xE04BD00C); /* sub sp,fp,ip */
823
997
o(0xE1A0F00E); /* mov pc,lr */
825
999
*(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
1241
static int is_zero(int i)
1243
if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1245
if (vtop[i].type.t == VT_FLOAT)
1246
return (vtop[i].c.f == 0.f);
1247
else if (vtop[i].type.t == VT_DOUBLE)
1248
return (vtop[i].c.d == 0.0);
1249
return (vtop[i].c.ld == 0.l);
1252
/* generate a floating point operation 'v = t1 op t2' instruction. The
1253
* two operands are guaranted to have the same floating point type */
1254
void gen_opf(int op)
1258
x=0xEE000A00|T2CPR(vtop->type.t);
1276
x|=0x810000; /* fsubX -> fnegX */
1289
if(op < TOK_ULT && op > TOK_GT) {
1290
error("unknown fp op %x!",op);
1296
case TOK_LT: op=TOK_GT; break;
1297
case TOK_GE: op=TOK_ULE; break;
1298
case TOK_LE: op=TOK_GE; break;
1299
case TOK_GT: op=TOK_ULT; break;
1302
x|=0xB40040; /* fcmpX */
1303
if(op!=TOK_EQ && op!=TOK_NE)
1304
x|=0x80; /* fcmpX -> fcmpeX */
1307
o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
1309
x|=vfpr(gv(RC_FLOAT));
1311
o(x|(vfpr(gv(RC_FLOAT))<<12));
1314
o(0xEEF1FA10); /* fmstat */
1317
case TOK_LE: op=TOK_ULE; break;
1318
case TOK_LT: op=TOK_ULT; break;
1319
case TOK_UGE: op=TOK_GE; break;
1320
case TOK_UGT: op=TOK_GT; break;
1337
vtop->r=get_reg_ex(RC_FLOAT,r);
1340
o(x|(vfpr(vtop->r)<<12));
1061
1344
static int is_fconst()
1194
1477
if(op >= TOK_ULT && op <= TOK_GT) {
1195
1478
x|=0xd0f110; // cmfe
1479
/* bug (intention?) in Linux FPU emulator
1480
doesn't set carry if equal */
1201
fputs("unsigned comparision on floats?\n",stderr);
1486
error("unsigned comparision on floats?");
1492
op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */
1279
1553
bt=vtop->type.t & VT_BTYPE;
1280
1554
if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
1281
1555
r=intr(gv(RC_INT));
1557
r2=vfpr(vtop->r=get_reg(RC_FLOAT));
1558
o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
1560
if(!(vtop->type.t & VT_UNSIGNED))
1561
r2|=0x80; /* fuitoX -> fsituX */
1562
o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
1282
1564
r2=fpr(vtop->r=get_reg(RC_FLOAT));
1283
1565
o(0xEE000190|(r2<<16)|(r<<12));
1284
1566
if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
1301
1583
o(0xBE000180|(r2<<16)|(r2<<12)|r);
1304
1587
} else if(bt == VT_LLONG) {
1589
CType *func_type = &func_old_type;
1592
func_type = &func_double_type;
1594
if((t & VT_BTYPE) == VT_FLOAT) {
1596
func_type = &func_float_type;
1598
if(vtop->type.t & VT_UNSIGNED)
1306
1604
if(vtop->type.t & VT_UNSIGNED)
1307
1605
func=TOK___ulltold;
1309
1607
func=TOK___slltold;
1310
vpush_global_sym(&func_old_type, func);
1608
vpush_global_sym(func_type, func);
1370
1677
/* convert from one floating point type to another */
1371
1678
void gen_cvt_ftof(int t)
1373
/* all we have to do on i386 and ARM is to put the float in a register */
1681
if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
1682
int r=vfpr(gv(RC_FLOAT));
1683
o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
1686
/* all we have to do on i386 and FPA ARM is to put the float in a register */
1377
1691
/* computed goto support */