History

clang-format on arm-gen.c and tcccoff.c.

They now mostly follow the same coding style as everything else.

gus knight committed 11 years ago

Commit 694d0fd1 parent 9e1b6bf2 files · +2155 −2140Browse files

Unified · Split

2 files
  1. arm-gen.c +1517 −1478
  2. tcccoff.c +638 −662
arm-gen.c+1517−1478
@@ -29,40 +29,40 @@ · 28 unmodified lines
2929
3030 /* number of available registers */
3131 #ifdef TCC_ARM_VFP
32−#define NB_REGS 13
32+#define NB_REGS 13
3333 #else
34−#define NB_REGS 9
34+#define NB_REGS 9
3535 #endif
3636
3737 typedef int RegArgs;
3838
3939 #ifndef TCC_ARM_VERSION
40−# define TCC_ARM_VERSION 5
40+#define TCC_ARM_VERSION 5
4141 #endif
4242
4343 /* a register can belong to several classes. The classes must be
4444 sorted from more general to more precise (see gv2() code which does
4545 assumptions on it). */
46−#define RC_INT 0x0001 /* generic integer register */
47−#define RC_FLOAT 0x0002 /* generic float register */
48−#define RC_R0 0x0004
49−#define RC_R1 0x0008
50−#define RC_R2 0x0010
51−#define RC_R3 0x0020
52−#define RC_R12 0x0040
53−#define RC_F0 0x0080
54−#define RC_F1 0x0100
55−#define RC_F2 0x0200
56−#define RC_F3 0x0400
46+#define RC_INT 0x0001 /* generic integer register */
47+#define RC_FLOAT 0x0002 /* generic float register */
48+#define RC_R0 0x0004
49+#define RC_R1 0x0008
50+#define RC_R2 0x0010
51+#define RC_R3 0x0020
52+#define RC_R12 0x0040
53+#define RC_F0 0x0080
54+#define RC_F1 0x0100
55+#define RC_F2 0x0200
56+#define RC_F3 0x0400
5757 #ifdef TCC_ARM_VFP
58−#define RC_F4 0x0800
59−#define RC_F5 0x1000
60−#define RC_F6 0x2000
61−#define RC_F7 0x4000
58+#define RC_F4 0x0800
59+#define RC_F5 0x1000
60+#define RC_F6 0x2000
61+#define RC_F7 0x4000
6262 #endif
63−#define RC_IRET RC_R0 /* function return: integer register */
64−#define RC_LRET RC_R1 /* function return: second integer register */
65−#define RC_FRET RC_F0 /* function return: float register */
63+#define RC_IRET RC_R0 /* function return: integer register */
64+#define RC_LRET RC_R1 /* function return: second integer register */
65+#define RC_FRET RC_F0 /* function return: float register */
6666
6767 /* pretty names for the registers */
6868 enum {
@@ -84,7 +84,7 @@ enum { · 15 unmodified lines
8484 };
8585
8686 #ifdef TCC_ARM_VFP
87−#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
87+#define T2CPR(t) (((t)&VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
8888 #endif
8989
9090 /* return registers for function */
@@ -111,11 +111,11 @@ enum { · 20 unmodified lines
111111
112112 /* long double size and alignment, in bytes */
113113 #ifdef TCC_ARM_VFP
114−#define LDOUBLE_SIZE 8
114+#define LDOUBLE_SIZE 8
115115 #endif
116116
117117 #ifndef LDOUBLE_SIZE
118−#define LDOUBLE_SIZE 8
118+#define LDOUBLE_SIZE 8
119119 #endif
120120
121121 #ifdef TCC_ARM_EABI
@@ -125,7 +125,7 @@ enum { · 3 unmodified lines
125125 #endif
126126
127127 /* maximum alignment (for aligned attribute support) */
128−#define MAX_ALIGN 8
128+#define MAX_ALIGN 8
129129
130130 #define CHAR_IS_UNSIGNED
131131
@@ -135,13 +135,13 @@ enum { · 3 unmodified lines
135135 #define EM_TCC_TARGET EM_ARM
136136
137137 /* relocation type for 32 bit data relocation */
138−#define R_DATA_32 R_ARM_ABS32
139−#define R_DATA_PTR R_ARM_ABS32
140−#define R_JMP_SLOT R_ARM_JUMP_SLOT
141−#define R_COPY R_ARM_COPY
138+#define R_DATA_32 R_ARM_ABS32
139+#define R_DATA_PTR R_ARM_ABS32
140+#define R_JMP_SLOT R_ARM_JUMP_SLOT
141+#define R_COPY R_ARM_COPY
142142
143143 #define ELF_START_ADDR 0x00008000
144−#define ELF_PAGE_SIZE 0x1000
144+#define ELF_PAGE_SIZE 0x1000
145145
146146 enum float_abi {
147147 ARM_SOFTFP_FLOAT,
@@ -166,10 +166,10 @@ ST_DATA const int reg_classes[NB_REGS] = { · 18 unmodified lines
166166 /* f2 */ RC_FLOAT | RC_F2,
167167 /* f3 */ RC_FLOAT | RC_F3,
168168 #ifdef TCC_ARM_VFP
169− /* d4/s8 */ RC_FLOAT | RC_F4,
170−/* d5/s10 */ RC_FLOAT | RC_F5,
171−/* d6/s12 */ RC_FLOAT | RC_F6,
172−/* d7/s14 */ RC_FLOAT | RC_F7,
169+ /* d4/s8 */ RC_FLOAT | RC_F4,
170+ /* d5/s10 */ RC_FLOAT | RC_F5,
171+ /* d6/s12 */ RC_FLOAT | RC_F6,
172+ /* d7/s14 */ RC_FLOAT | RC_F7,
173173 #endif
174174 };
175175
@@ -178,14 +178,16 @@ static int leaffunc; · 2 unmodified lines
178178
179179 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
180180 static CType float_type, double_type, func_float_type, func_double_type;
181−ST_FUNC void arm_init(struct TCCState *s)
181+ST_FUNC void arm_init(struct TCCState* s)
182182 {
183183 float_type.t = VT_FLOAT;
184184 double_type.t = VT_DOUBLE;
185185 func_float_type.t = VT_FUNC;
186− func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
186+ func_float_type.ref =
187+ sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
187188 func_double_type.t = VT_FUNC;
188− func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
189+ func_double_type.ref =
190+ sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
189191
190192 float_abi = s->float_abi;
191193 #ifndef TCC_ARM_HARDFLOAT
@@ -196,31 +198,33 @@ ST_FUNC void arm_init(struct TCCState *s) · 4 unmodified lines
196198 #define func_float_type func_old_type
197199 #define func_double_type func_old_type
198200 #define func_ldouble_type func_old_type
199−ST_FUNC void arm_init(struct TCCState *s)
201+ST_FUNC void arm_init(struct TCCState* s)
200202 {
201−#if !defined (TCC_ARM_VFP)
203+#if !defined(TCC_ARM_VFP)
202204 tcc_warning("Support for FPA is deprecated and will be removed in next"
203205 " release");
204206 #endif
205−#if !defined (TCC_ARM_EABI)
207+#if !defined(TCC_ARM_EABI)
206208 tcc_warning("Support for OABI is deprecated and will be removed in next"
207209 " release");
208210 #endif
209211 }
210212 #endif
211213
212−static int two2mask(int a,int b) {
213− return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
214+static int two2mask(int a, int b)
215+{
216+ return (reg_classes[a] | reg_classes[b]) & ~(RC_INT | RC_FLOAT);
214217 }
215218
216−static int regmask(int r) {
217− return reg_classes[r]&~(RC_INT|RC_FLOAT);
219+static int regmask(int r)
220+{
221+ return reg_classes[r] & ~(RC_INT | RC_FLOAT);
218222 }
219223
220224 /******************************************************/
221225
222226 #if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
223−char *default_elfinterp(struct TCCState *s)
227+char* default_elfinterp(struct TCCState* s)
224228 {
225229 if (s->float_abi == ARM_HARD_FLOAT)
226230 return "/lib/ld-linux-armhf.so.3";
@@ -231,551 +235,554 @@ char *default_elfinterp(struct TCCState *s) · 4 unmodified lines
231235
232236 void o(uint32_t i)
233237 {
234− /* this is a good place to start adding big-endian support*/
235− int ind1;
236−
237− ind1 = ind + 4;
238− if (!cur_text_section)
239− tcc_error("compiler error! This happens f.ex. if the compiler\n"
240− "can't evaluate constant expressions outside of a function.");
241− if (ind1 > cur_text_section->data_allocated)
242− section_realloc(cur_text_section, ind1);
243− cur_text_section->data[ind++] = i&255;
244− i>>=8;
245− cur_text_section->data[ind++] = i&255;
246− i>>=8;
247− cur_text_section->data[ind++] = i&255;
248− i>>=8;
249− cur_text_section->data[ind++] = i;
238+ /* this is a good place to start adding big-endian support*/
239+ int ind1;
240+
241+ ind1 = ind + 4;
242+ if (!cur_text_section)
243+ tcc_error("compiler error! This happens f.ex. if the compiler\n"
244+ "can't evaluate constant expressions outside of a function.");
245+ if (ind1 > cur_text_section->data_allocated)
246+ section_realloc(cur_text_section, ind1);
247+ cur_text_section->data[ind++] = i & 255;
248+ i >>= 8;
249+ cur_text_section->data[ind++] = i & 255;
250+ i >>= 8;
251+ cur_text_section->data[ind++] = i & 255;
252+ i >>= 8;
253+ cur_text_section->data[ind++] = i;
250254 }
251255
252256 static uint32_t stuff_const(uint32_t op, uint32_t c)
253257 {
254− int try_neg=0;
255− uint32_t nc = 0, negop = 0;
256−
257− switch(op&0x1F00000)
258− {
259− case 0x800000: //add
260− case 0x400000: //sub
261− try_neg=1;
262− negop=op^0xC00000;
263− nc=-c;
264− break;
265− case 0x1A00000: //mov
266− case 0x1E00000: //mvn
267− try_neg=1;
268− negop=op^0x400000;
269− nc=~c;
270− break;
271− case 0x200000: //xor
272− if(c==~0)
273− return (op&0xF010F000)|((op>>16)&0xF)|0x1E00000;
274− break;
275− case 0x0: //and
276− if(c==~0)
277− return (op&0xF010F000)|((op>>16)&0xF)|0x1A00000;
278− case 0x1C00000: //bic
279− try_neg=1;
280− negop=op^0x1C00000;
281− nc=~c;
282− break;
283− case 0x1800000: //orr
284− if(c==~0)
285− return (op&0xFFF0FFFF)|0x1E00000;
286− break;
287− }
288− do {
289− uint32_t m;
290− int i;
291− if(c<256) /* catch undefined <<32 */
292− return op|c;
293− for(i=2;i<32;i+=2) {
294− m=(0xff>>i)|(0xff<<(32-i));
295− if(!(c&~m))
296− return op|(i<<7)|(c<<i)|(c>>(32-i));
258+ int try_neg = 0;
259+ uint32_t nc = 0, negop = 0;
260+
261+ switch (op & 0x1F00000) {
262+ case 0x800000: // add
263+ case 0x400000: // sub
264+ try_neg = 1;
265+ negop = op ^ 0xC00000;
266+ nc = -c;
267+ break;
268+ case 0x1A00000: // mov
269+ case 0x1E00000: // mvn
270+ try_neg = 1;
271+ negop = op ^ 0x400000;
272+ nc = ~c;
273+ break;
274+ case 0x200000: // xor
275+ if (c == ~0)
276+ return (op & 0xF010F000) | ((op >> 16) & 0xF) | 0x1E00000;
277+ break;
278+ case 0x0: // and
279+ if (c == ~0)
280+ return (op & 0xF010F000) | ((op >> 16) & 0xF) | 0x1A00000;
281+ case 0x1C00000: // bic
282+ try_neg = 1;
283+ negop = op ^ 0x1C00000;
284+ nc = ~c;
285+ break;
286+ case 0x1800000: // orr
287+ if (c == ~0)
288+ return (op & 0xFFF0FFFF) | 0x1E00000;
289+ break;
297290 }
298− op=negop;
299− c=nc;
300− } while(try_neg--);
301− return 0;
291+ do {
292+ uint32_t m;
293+ int i;
294+ if (c < 256) /* catch undefined <<32 */
295+ return op | c;
296+ for (i = 2; i < 32; i += 2) {
297+ m = (0xff >> i) | (0xff << (32 - i));
298+ if (!(c & ~m))
299+ return op | (i << 7) | (c << i) | (c >> (32 - i));
300+ }
301+ op = negop;
302+ c = nc;
303+ } while (try_neg--);
304+ return 0;
302305 }
303306
304−
305−//only add,sub
306−void stuff_const_harder(uint32_t op, uint32_t v) {
307− uint32_t x;
308− x=stuff_const(op,v);
309− if(x)
310− o(x);
311− else {
312− uint32_t a[16], nv, no, o2, n2;
313− int i,j,k;
314− a[0]=0xff;
315− o2=(op&0xfff0ffff)|((op&0xf000)<<4);;
316− for(i=1;i<16;i++)
317− a[i]=(a[i-1]>>2)|(a[i-1]<<30);
318− for(i=0;i<12;i++)
319− for(j=i<4?i+12:15;j>=i+4;j--)
320− if((v&(a[i]|a[j]))==v) {
321− o(stuff_const(op,v&a[i]));
322− o(stuff_const(o2,v&a[j]));
323− return;
324− }
325− no=op^0xC00000;
326− n2=o2^0xC00000;
327− nv=-v;
328− for(i=0;i<12;i++)
329− for(j=i<4?i+12:15;j>=i+4;j--)
330− if((nv&(a[i]|a[j]))==nv) {
331− o(stuff_const(no,nv&a[i]));
332− o(stuff_const(n2,nv&a[j]));
333− return;
334− }
335− for(i=0;i<8;i++)
336− for(j=i+4;j<12;j++)
337− for(k=i<4?i+12:15;k>=j+4;k--)
338− if((v&(a[i]|a[j]|a[k]))==v) {
339− o(stuff_const(op,v&a[i]));
340− o(stuff_const(o2,v&a[j]));
341− o(stuff_const(o2,v&a[k]));
342− return;
343− }
344− no=op^0xC00000;
345− nv=-v;
346− for(i=0;i<8;i++)
347− for(j=i+4;j<12;j++)
348− for(k=i<4?i+12:15;k>=j+4;k--)
349− if((nv&(a[i]|a[j]|a[k]))==nv) {
350− o(stuff_const(no,nv&a[i]));
351− o(stuff_const(n2,nv&a[j]));
352− o(stuff_const(n2,nv&a[k]));
353− return;
354− }
355− o(stuff_const(op,v&a[0]));
356− o(stuff_const(o2,v&a[4]));
357− o(stuff_const(o2,v&a[8]));
358− o(stuff_const(o2,v&a[12]));
359− }
307+// only add,sub
308+void stuff_const_harder(uint32_t op, uint32_t v)
309+{
310+ uint32_t x;
311+ x = stuff_const(op, v);
312+ if (x)
313+ o(x);
314+ else {
315+ uint32_t a[16], nv, no, o2, n2;
316+ int i, j, k;
317+ a[0] = 0xff;
318+ o2 = (op & 0xfff0ffff) | ((op & 0xf000) << 4);
319+ ;
320+ for (i = 1; i < 16; i++)
321+ a[i] = (a[i - 1] >> 2) | (a[i - 1] << 30);
322+ for (i = 0; i < 12; i++)
323+ for (j = i < 4 ? i + 12 : 15; j >= i + 4; j--)
324+ if ((v & (a[i] | a[j])) == v) {
325+ o(stuff_const(op, v & a[i]));
326+ o(stuff_const(o2, v & a[j]));
327+ return;
328+ }
329+ no = op ^ 0xC00000;
330+ n2 = o2 ^ 0xC00000;
331+ nv = -v;
332+ for (i = 0; i < 12; i++)
333+ for (j = i < 4 ? i + 12 : 15; j >= i + 4; j--)
334+ if ((nv & (a[i] | a[j])) == nv) {
335+ o(stuff_const(no, nv & a[i]));
336+ o(stuff_const(n2, nv & a[j]));
337+ return;
338+ }
339+ for (i = 0; i < 8; i++)
340+ for (j = i + 4; j < 12; j++)
341+ for (k = i < 4 ? i + 12 : 15; k >= j + 4; k--)
342+ if ((v & (a[i] | a[j] | a[k])) == v) {
343+ o(stuff_const(op, v & a[i]));
344+ o(stuff_const(o2, v & a[j]));
345+ o(stuff_const(o2, v & a[k]));
346+ return;
347+ }
348+ no = op ^ 0xC00000;
349+ nv = -v;
350+ for (i = 0; i < 8; i++)
351+ for (j = i + 4; j < 12; j++)
352+ for (k = i < 4 ? i + 12 : 15; k >= j + 4; k--)
353+ if ((nv & (a[i] | a[j] | a[k])) == nv) {
354+ o(stuff_const(no, nv & a[i]));
355+ o(stuff_const(n2, nv & a[j]));
356+ o(stuff_const(n2, nv & a[k]));
357+ return;
358+ }
359+ o(stuff_const(op, v & a[0]));
360+ o(stuff_const(o2, v & a[4]));
361+ o(stuff_const(o2, v & a[8]));
362+ o(stuff_const(o2, v & a[12]));
363+ }
360364 }
361365
362366 ST_FUNC uint32_t encbranch(int pos, int addr, int fail)
363367 {
364− addr-=pos+8;
365− addr/=4;
366− if(addr>=0x1000000 || addr<-0x1000000) {
367− if(fail)
368− tcc_error("FIXME: function bigger than 32MB");
369− return 0;
370− }
371− return 0x0A000000|(addr&0xffffff);
368+ addr -= pos + 8;
369+ addr /= 4;
370+ if (addr >= 0x1000000 || addr < -0x1000000) {
371+ if (fail)
372+ tcc_error("FIXME: function bigger than 32MB");
373+ return 0;
374+ }
375+ return 0x0A000000 | (addr & 0xffffff);
372376 }
373377
374378 int decbranch(int pos)
375379 {
376− int x;
377− x=*(uint32_t *)(cur_text_section->data + pos);
378− x&=0x00ffffff;
379− if(x&0x800000)
380− x-=0x1000000;
381− return x*4+pos+8;
380+ int x;
381+ x = *(uint32_t*)(cur_text_section->data + pos);
382+ x &= 0x00ffffff;
383+ if (x & 0x800000)
384+ x -= 0x1000000;
385+ return x * 4 + pos + 8;
382386 }
383387
384388 /* output a symbol and patch all calls to it */
385389 void gsym_addr(int t, int a)
386390 {
387− uint32_t *x;
388− int lt;
389− while(t) {
390− x=(uint32_t *)(cur_text_section->data + t);
391− t=decbranch(lt=t);
392− if(a==lt+4)
393− *x=0xE1A00000; // nop
394− else {
395− *x &= 0xff000000;
396− *x |= encbranch(lt,a,1);
391+ uint32_t* x;
392+ int lt;
393+ while (t) {
394+ x = (uint32_t*)(cur_text_section->data + t);
395+ t = decbranch(lt = t);
396+ if (a == lt + 4)
397+ *x = 0xE1A00000; // nop
398+ else {
399+ *x &= 0xff000000;
400+ *x |= encbranch(lt, a, 1);
401+ }
397402 }
398− }
399403 }
400404
401405 void gsym(int t)
402406 {
403− gsym_addr(t, ind);
407+ gsym_addr(t, ind);
404408 }
405409
406410 #ifdef TCC_ARM_VFP
407411 static uint32_t vfpr(int r)
408412 {
409− if(r<TREG_F0 || r>TREG_F7)
410− tcc_error("compiler error! register %i is no vfp register",r);
411− return r-5;
413+ if (r < TREG_F0 || r > TREG_F7)
414+ tcc_error("compiler error! register %i is no vfp register", r);
415+ return r - 5;
412416 }
413417 #else
414418 static uint32_t fpr(int r)
415419 {
416− if(r<TREG_F0 || r>TREG_F3)
417− tcc_error("compiler error! register %i is no fpa register",r);
418− return r-5;
420+ if (r < TREG_F0 || r > TREG_F3)
421+ tcc_error("compiler error! register %i is no fpa register", r);
422+ return r - 5;
419423 }
420424 #endif
421425
422426 static uint32_t intr(int r)
423427 {
424− if(r==4)
425− return 12;
426− if((r<0 || r>4) && r!=14)
427− tcc_error("compiler error! register %i is no int register",r);
428− return r;
428+ if (r == 4)
429+ return 12;
430+ if ((r < 0 || r > 4) && r != 14)
431+ tcc_error("compiler error! register %i is no int register", r);
432+ return r;
429433 }
430434
431−static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
435+static void calcaddr(uint32_t* base, int* off, int* sgn, int maxoff,
436+ unsigned shift)
432437 {
433− if(*off>maxoff || *off&((1<<shift)-1)) {
434− uint32_t x, y;
435− x=0xE280E000;
436− if(*sgn)
437− x=0xE240E000;
438− x|=(*base)<<16;
439− *base=14; // lr
440− y=stuff_const(x,*off&~maxoff);
441− if(y) {
442− o(y);
443− *off&=maxoff;
444− return;
445− }
446− y=stuff_const(x,(*off+maxoff)&~maxoff);
447− if(y) {
448− o(y);
449− *sgn=!*sgn;
450− *off=((*off+maxoff)&~maxoff)-*off;
451− return;
438+ if (*off > maxoff || *off & ((1 << shift) - 1)) {
439+ uint32_t x, y;
440+ x = 0xE280E000;
441+ if (*sgn)
442+ x = 0xE240E000;
443+ x |= (*base) << 16;
444+ *base = 14; // lr
445+ y = stuff_const(x, *off & ~maxoff);
446+ if (y) {
447+ o(y);
448+ *off &= maxoff;
449+ return;
450+ }
451+ y = stuff_const(x, (*off + maxoff) & ~maxoff);
452+ if (y) {
453+ o(y);
454+ *sgn = !*sgn;
455+ *off = ((*off + maxoff) & ~maxoff) - *off;
456+ return;
457+ }
458+ stuff_const_harder(x, *off & ~maxoff);
459+ *off &= maxoff;
452460 }
453− stuff_const_harder(x,*off&~maxoff);
454− *off&=maxoff;
455− }
456461 }
457462
458463 static uint32_t mapcc(int cc)
459464 {
460− switch(cc)
461− {
465+ switch (cc) {
462466 case TOK_ULT:
463− return 0x30000000; /* CC/LO */
467+ return 0x30000000; /* CC/LO */
464468 case TOK_UGE:
465− return 0x20000000; /* CS/HS */
469+ return 0x20000000; /* CS/HS */
466470 case TOK_EQ:
467− return 0x00000000; /* EQ */
471+ return 0x00000000; /* EQ */
468472 case TOK_NE:
469− return 0x10000000; /* NE */
473+ return 0x10000000; /* NE */
470474 case TOK_ULE:
471− return 0x90000000; /* LS */
475+ return 0x90000000; /* LS */
472476 case TOK_UGT:
473− return 0x80000000; /* HI */
477+ return 0x80000000; /* HI */
474478 case TOK_Nset:
475− return 0x40000000; /* MI */
479+ return 0x40000000; /* MI */
476480 case TOK_Nclear:
477− return 0x50000000; /* PL */
481+ return 0x50000000; /* PL */
478482 case TOK_LT:
479− return 0xB0000000; /* LT */
483+ return 0xB0000000; /* LT */
480484 case TOK_GE:
481− return 0xA0000000; /* GE */
485+ return 0xA0000000; /* GE */
482486 case TOK_LE:
483− return 0xD0000000; /* LE */
487+ return 0xD0000000; /* LE */
484488 case TOK_GT:
485− return 0xC0000000; /* GT */
486− }
487− tcc_error("unexpected condition code");
488− return 0xE0000000; /* AL */
489+ return 0xC0000000; /* GT */
490+ }
491+ tcc_error("unexpected condition code");
492+ return 0xE0000000; /* AL */
489493 }
490494
491495 static int negcc(int cc)
492496 {
493− switch(cc)
494− {
497+ switch (cc) {
495498 case TOK_ULT:
496− return TOK_UGE;
499+ return TOK_UGE;
497500 case TOK_UGE:
498− return TOK_ULT;
501+ return TOK_ULT;
499502 case TOK_EQ:
500− return TOK_NE;
503+ return TOK_NE;
501504 case TOK_NE:
502− return TOK_EQ;
505+ return TOK_EQ;
503506 case TOK_ULE:
504− return TOK_UGT;
507+ return TOK_UGT;
505508 case TOK_UGT:
506− return TOK_ULE;
509+ return TOK_ULE;
507510 case TOK_Nset:
508− return TOK_Nclear;
511+ return TOK_Nclear;
509512 case TOK_Nclear:
510− return TOK_Nset;
513+ return TOK_Nset;
511514 case TOK_LT:
512− return TOK_GE;
515+ return TOK_GE;
513516 case TOK_GE:
514− return TOK_LT;
517+ return TOK_LT;
515518 case TOK_LE:
516− return TOK_GT;
519+ return TOK_GT;
517520 case TOK_GT:
518− return TOK_LE;
519− }
520− tcc_error("unexpected condition code");
521− return TOK_NE;
521+ return TOK_LE;
522+ }
523+ tcc_error("unexpected condition code");
524+ return TOK_NE;
522525 }
523526
524527 /* load 'r' from value 'sv' */
525−void load(int r, SValue *sv)
528+void load(int r, SValue* sv)
526529 {
527− int v, ft, fc, fr, sign;
528− uint32_t op;
529− SValue v1;
530−
531− fr = sv->r;
532− ft = sv->type.t;
533− fc = sv->c.ul;
534−
535− if(fc>=0)
536− sign=0;
537− else {
538− sign=1;
539− fc=-fc;
540− }
541−
542− v = fr & VT_VALMASK;
543− if (fr & VT_LVAL) {
544− uint32_t base = 0xB; // fp
545− if(v == VT_LLOCAL) {
546− v1.type.t = VT_PTR;
547− v1.r = VT_LOCAL | VT_LVAL;
548− v1.c.ul = sv->c.ul;
549− load(base=14 /* lr */, &v1);
550− fc=sign=0;
551− v=VT_LOCAL;
552− } else if(v == VT_CONST) {
553− v1.type.t = VT_PTR;
554− v1.r = fr&~VT_LVAL;
555− v1.c.ul = sv->c.ul;
556− v1.sym=sv->sym;
557− load(base=14, &v1);
558− fc=sign=0;
559− v=VT_LOCAL;
560− } else if(v < VT_CONST) {
561− base=intr(v);
562− fc=sign=0;
563− v=VT_LOCAL;
530+ int v, ft, fc, fr, sign;
531+ uint32_t op;
532+ SValue v1;
533+
534+ fr = sv->r;
535+ ft = sv->type.t;
536+ fc = sv->c.ul;
537+
538+ if (fc >= 0)
539+ sign = 0;
540+ else {
541+ sign = 1;
542+ fc = -fc;
564543 }
565− if(v == VT_LOCAL) {
566− if(is_float(ft)) {
567− calcaddr(&base,&fc,&sign,1020,2);
544+
545+ v = fr & VT_VALMASK;
546+ if (fr & VT_LVAL) {
547+ uint32_t base = 0xB; // fp
548+ if (v == VT_LLOCAL) {
549+ v1.type.t = VT_PTR;
550+ v1.r = VT_LOCAL | VT_LVAL;
551+ v1.c.ul = sv->c.ul;
552+ load(base = 14 /* lr */, &v1);
553+ fc = sign = 0;
554+ v = VT_LOCAL;
555+ } else if (v == VT_CONST) {
556+ v1.type.t = VT_PTR;
557+ v1.r = fr & ~VT_LVAL;
558+ v1.c.ul = sv->c.ul;
559+ v1.sym = sv->sym;
560+ load(base = 14, &v1);
561+ fc = sign = 0;
562+ v = VT_LOCAL;
563+ } else if (v < VT_CONST) {
564+ base = intr(v);
565+ fc = sign = 0;
566+ v = VT_LOCAL;
567+ }
568+ if (v == VT_LOCAL) {
569+ if (is_float(ft)) {
570+ calcaddr(&base, &fc, &sign, 1020, 2);
568571 #ifdef TCC_ARM_VFP
569− op=0xED100A00; /* flds */
570− if(!sign)
571− op|=0x800000;
572− if ((ft & VT_BTYPE) != VT_FLOAT)
573− op|=0x100; /* flds -> fldd */
574− o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
572+ op = 0xED100A00; /* flds */
573+ if (!sign)
574+ op |= 0x800000;
575+ if ((ft & VT_BTYPE) != VT_FLOAT)
576+ op |= 0x100; /* flds -> fldd */
577+ o(op | (vfpr(r) << 12) | (fc >> 2) | (base << 16));
575578 #else
576− op=0xED100100;
577− if(!sign)
578− op|=0x800000;
579+ op = 0xED100100;
580+ if (!sign)
581+ op |= 0x800000;
579582 #if LDOUBLE_SIZE == 8
580− if ((ft & VT_BTYPE) != VT_FLOAT)
581− op|=0x8000;
583+ if ((ft & VT_BTYPE) != VT_FLOAT)
584+ op |= 0x8000;
582585 #else
583− if ((ft & VT_BTYPE) == VT_DOUBLE)
584− op|=0x8000;
585− else if ((ft & VT_BTYPE) == VT_LDOUBLE)
586− op|=0x400000;
586+ if ((ft & VT_BTYPE) == VT_DOUBLE)
587+ op |= 0x8000;
588+ else if ((ft & VT_BTYPE) == VT_LDOUBLE)
589+ op |= 0x400000;
587590 #endif
588− o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
591+ o(op | (fpr(r) << 12) | (fc >> 2) | (base << 16));
589592 #endif
590− } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
591− || (ft & VT_BTYPE) == VT_SHORT) {
592− calcaddr(&base,&fc,&sign,255,0);
593− op=0xE1500090;
594− if ((ft & VT_BTYPE) == VT_SHORT)
595− op|=0x20;
596− if ((ft & VT_UNSIGNED) == 0)
597− op|=0x40;
598− if(!sign)
599− op|=0x800000;
600− o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
601− } else {
602− calcaddr(&base,&fc,&sign,4095,0);
603− op=0xE5100000;
604− if(!sign)
605− op|=0x800000;
606− if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
607− op|=0x400000;
608− o(op|(intr(r)<<12)|fc|(base<<16));
609− }
610− return;
611− }
612− } else {
613− if (v == VT_CONST) {
614− op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul);
615− if (fr & VT_SYM || !op) {
616− o(0xE59F0000|(intr(r)<<12));
617− o(0xEA000000);
618− if(fr & VT_SYM)
619− greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
620− o(sv->c.ul);
621− } else
622− o(op);
623− return;
624− } else if (v == VT_LOCAL) {
625− op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul);
626− if (fr & VT_SYM || !op) {
627− o(0xE59F0000|(intr(r)<<12));
628− o(0xEA000000);
629− if(fr & VT_SYM) // needed ?
630− greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
631− o(sv->c.ul);
632− o(0xE08B0000|(intr(r)<<12)|intr(r));
633− } else
634− o(op);
635− return;
636− } else if(v == VT_CMP) {
637− o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12));
638− o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12));
639− return;
640− } else if (v == VT_JMP || v == VT_JMPI) {
641− int t;
642− t = v & 1;
643− o(0xE3A00000|(intr(r)<<12)|t);
644− o(0xEA000000);
645− gsym(sv->c.ul);
646− o(0xE3A00000|(intr(r)<<12)|(t^1));
647− return;
648− } else if (v < VT_CONST) {
649− if(is_float(ft))
593+ } else if ((ft & (VT_BTYPE | VT_UNSIGNED)) == VT_BYTE ||
594+ (ft & VT_BTYPE) == VT_SHORT) {
595+ calcaddr(&base, &fc, &sign, 255, 0);
596+ op = 0xE1500090;
597+ if ((ft & VT_BTYPE) == VT_SHORT)
598+ op |= 0x20;
599+ if ((ft & VT_UNSIGNED) == 0)
600+ op |= 0x40;
601+ if (!sign)
602+ op |= 0x800000;
603+ o(op | (intr(r) << 12) | (base << 16) | ((fc & 0xf0) << 4) |
604+ (fc & 0xf));
605+ } else {
606+ calcaddr(&base, &fc, &sign, 4095, 0);
607+ op = 0xE5100000;
608+ if (!sign)
609+ op |= 0x800000;
610+ if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
611+ op |= 0x400000;
612+ o(op | (intr(r) << 12) | fc | (base << 16));
613+ }
614+ return;
615+ }
616+ } else {
617+ if (v == VT_CONST) {
618+ op = stuff_const(0xE3A00000 | (intr(r) << 12), sv->c.ul);
619+ if (fr & VT_SYM || !op) {
620+ o(0xE59F0000 | (intr(r) << 12));
621+ o(0xEA000000);
622+ if (fr & VT_SYM)
623+ greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
624+ o(sv->c.ul);
625+ } else
626+ o(op);
627+ return;
628+ } else if (v == VT_LOCAL) {
629+ op = stuff_const(0xE28B0000 | (intr(r) << 12), sv->c.ul);
630+ if (fr & VT_SYM || !op) {
631+ o(0xE59F0000 | (intr(r) << 12));
632+ o(0xEA000000);
633+ if (fr & VT_SYM) // needed ?
634+ greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
635+ o(sv->c.ul);
636+ o(0xE08B0000 | (intr(r) << 12) | intr(r));
637+ } else
638+ o(op);
639+ return;
640+ } else if (v == VT_CMP) {
641+ o(mapcc(sv->c.ul) | 0x3A00001 | (intr(r) << 12));
642+ o(mapcc(negcc(sv->c.ul)) | 0x3A00000 | (intr(r) << 12));
643+ return;
644+ } else if (v == VT_JMP || v == VT_JMPI) {
645+ int t;
646+ t = v & 1;
647+ o(0xE3A00000 | (intr(r) << 12) | t);
648+ o(0xEA000000);
649+ gsym(sv->c.ul);
650+ o(0xE3A00000 | (intr(r) << 12) | (t ^ 1));
651+ return;
652+ } else if (v < VT_CONST) {
653+ if (is_float(ft))
650654 #ifdef TCC_ARM_VFP
651− o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
655+ o(0xEEB00A40 | (vfpr(r) << 12) | vfpr(v) |
656+ T2CPR(ft)); /* fcpyX */
652657 #else
653− o(0xEE008180|(fpr(r)<<12)|fpr(v));
658+ o(0xEE008180 | (fpr(r) << 12) | fpr(v));
654659 #endif
655− else
656− o(0xE1A00000|(intr(r)<<12)|intr(v));
657− return;
660+ else
661+ o(0xE1A00000 | (intr(r) << 12) | intr(v));
662+ return;
663+ }
658664 }
659− }
660− tcc_error("load unimplemented!");
665+ tcc_error("load unimplemented!");
661666 }
662667
663668 /* store register 'r' in lvalue 'v' */
664−void store(int r, SValue *sv)
669+void store(int r, SValue* sv)
665670 {
666− SValue v1;
667− int v, ft, fc, fr, sign;
668− uint32_t op;
669−
670− fr = sv->r;
671− ft = sv->type.t;
672− fc = sv->c.ul;
673−
674− if(fc>=0)
675− sign=0;
676− else {
677− sign=1;
678− fc=-fc;
679− }
680−
681− v = fr & VT_VALMASK;
682− if (fr & VT_LVAL || fr == VT_LOCAL) {
683− uint32_t base = 0xb;
684− if(v < VT_CONST) {
685− base=intr(v);
686− v=VT_LOCAL;
687− fc=sign=0;
688− } else if(v == VT_CONST) {
689− v1.type.t = ft;
690− v1.r = fr&~VT_LVAL;
691− v1.c.ul = sv->c.ul;
692− v1.sym=sv->sym;
693− load(base=14, &v1);
694− fc=sign=0;
695− v=VT_LOCAL;
671+ SValue v1;
672+ int v, ft, fc, fr, sign;
673+ uint32_t op;
674+
675+ fr = sv->r;
676+ ft = sv->type.t;
677+ fc = sv->c.ul;
678+
679+ if (fc >= 0)
680+ sign = 0;
681+ else {
682+ sign = 1;
683+ fc = -fc;
696684 }
697− if(v == VT_LOCAL) {
698− if(is_float(ft)) {
699− calcaddr(&base,&fc,&sign,1020,2);
685+
686+ v = fr & VT_VALMASK;
687+ if (fr & VT_LVAL || fr == VT_LOCAL) {
688+ uint32_t base = 0xb;
689+ if (v < VT_CONST) {
690+ base = intr(v);
691+ v = VT_LOCAL;
692+ fc = sign = 0;
693+ } else if (v == VT_CONST) {
694+ v1.type.t = ft;
695+ v1.r = fr & ~VT_LVAL;
696+ v1.c.ul = sv->c.ul;
697+ v1.sym = sv->sym;
698+ load(base = 14, &v1);
699+ fc = sign = 0;
700+ v = VT_LOCAL;
701+ }
702+ if (v == VT_LOCAL) {
703+ if (is_float(ft)) {
704+ calcaddr(&base, &fc, &sign, 1020, 2);
700705 #ifdef TCC_ARM_VFP
701− op=0xED000A00; /* fsts */
702− if(!sign)
703− op|=0x800000;
704− if ((ft & VT_BTYPE) != VT_FLOAT)
705− op|=0x100; /* fsts -> fstd */
706− o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
706+ op = 0xED000A00; /* fsts */
707+ if (!sign)
708+ op |= 0x800000;
709+ if ((ft & VT_BTYPE) != VT_FLOAT)
710+ op |= 0x100; /* fsts -> fstd */
711+ o(op | (vfpr(r) << 12) | (fc >> 2) | (base << 16));
707712 #else
708− op=0xED000100;
709− if(!sign)
710− op|=0x800000;
713+ op = 0xED000100;
714+ if (!sign)
715+ op |= 0x800000;
711716 #if LDOUBLE_SIZE == 8
712− if ((ft & VT_BTYPE) != VT_FLOAT)
713− op|=0x8000;
717+ if ((ft & VT_BTYPE) != VT_FLOAT)
718+ op |= 0x8000;
714719 #else
715− if ((ft & VT_BTYPE) == VT_DOUBLE)
716− op|=0x8000;
717− if ((ft & VT_BTYPE) == VT_LDOUBLE)
718− op|=0x400000;
720+ if ((ft & VT_BTYPE) == VT_DOUBLE)
721+ op |= 0x8000;
722+ if ((ft & VT_BTYPE) == VT_LDOUBLE)
723+ op |= 0x400000;
719724 #endif
720− o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
725+ o(op | (fpr(r) << 12) | (fc >> 2) | (base << 16));
721726 #endif
722− return;
723− } else if((ft & VT_BTYPE) == VT_SHORT) {
724− calcaddr(&base,&fc,&sign,255,0);
725− op=0xE14000B0;
726− if(!sign)
727− op|=0x800000;
728− o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
729− } else {
730− calcaddr(&base,&fc,&sign,4095,0);
731− op=0xE5000000;
732− if(!sign)
733− op|=0x800000;
734− if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
735− op|=0x400000;
736− o(op|(intr(r)<<12)|fc|(base<<16));
737− }
738− return;
727+ return;
728+ } else if ((ft & VT_BTYPE) == VT_SHORT) {
729+ calcaddr(&base, &fc, &sign, 255, 0);
730+ op = 0xE14000B0;
731+ if (!sign)
732+ op |= 0x800000;
733+ o(op | (intr(r) << 12) | (base << 16) | ((fc & 0xf0) << 4) |
734+ (fc & 0xf));
735+ } else {
736+ calcaddr(&base, &fc, &sign, 4095, 0);
737+ op = 0xE5000000;
738+ if (!sign)
739+ op |= 0x800000;
740+ if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
741+ op |= 0x400000;
742+ o(op | (intr(r) << 12) | fc | (base << 16));
743+ }
744+ return;
745+ }
739746 }
740− }
741− tcc_error("store unimplemented");
747+ tcc_error("store unimplemented");
742748 }
743749
744750 static void gadd_sp(int val)
745751 {
746− stuff_const_harder(0xE28DD000,val);
752+ stuff_const_harder(0xE28DD000, val);
747753 }
748754
749755 /* 'is_jmp' is '1' if it is a jump */
750756 static void gcall_or_jmp(int is_jmp)
751757 {
752− int r;
753− if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
754− uint32_t x;
755− /* constant case */
756− x=encbranch(ind,ind+vtop->c.ul,0);
757− if(x) {
758− if (vtop->r & VT_SYM) {
759− /* relocation case */
760− greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
761− } else
762− put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
763− o(x|(is_jmp?0xE0000000:0xE1000000));
758+ int r;
759+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
760+ uint32_t x;
761+ /* constant case */
762+ x = encbranch(ind, ind + vtop->c.ul, 0);
763+ if (x) {
764+ if (vtop->r & VT_SYM) {
765+ /* relocation case */
766+ greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
767+ } else
768+ put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24,
769+ 0);
770+ o(x | (is_jmp ? 0xE0000000 : 0xE1000000));
771+ } else {
772+ if (!is_jmp)
773+ o(0xE28FE004); // add lr,pc,#4
774+ o(0xE51FF004); // ldr pc,[pc,#-4]
775+ if (vtop->r & VT_SYM)
776+ greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
777+ o(vtop->c.ul);
778+ }
764779 } else {
765− if(!is_jmp)
766− o(0xE28FE004); // add lr,pc,#4
767− o(0xE51FF004); // ldr pc,[pc,#-4]
768− if (vtop->r & VT_SYM)
769− greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
770− o(vtop->c.ul);
780+ /* otherwise, indirect call */
781+ r = gv(RC_INT);
782+ if (!is_jmp)
783+ o(0xE1A0E00F); // mov lr,pc
784+ o(0xE1A0F000 | intr(r)); // mov pc,r
771785 }
772− } else {
773− /* otherwise, indirect call */
774− r = gv(RC_INT);
775− if(!is_jmp)
776− o(0xE1A0E00F); // mov lr,pc
777− o(0xE1A0F000|intr(r)); // mov pc,r
778− }
779786 }
780787
781788 /* Return whether a structure is an homogeneous float aggregate or not.
@@ -783,27 +790,30 @@ static void gcall_or_jmp(int is_jmp) · 1 unmodified line
783790 primitive float type and there is less than 4 elements.
784791
785792 type: the type corresponding to the structure to be tested */
786−static int is_hgen_float_aggr(CType *type)
793+static int is_hgen_float_aggr(CType* type)
787794 {
788− if ((type->t & VT_BTYPE) == VT_STRUCT) {
789− struct Sym *ref;
790− int btype, nb_fields = 0;
791−
792− ref = type->ref->next;
793− btype = ref->type.t & VT_BTYPE;
794− if (btype == VT_FLOAT || btype == VT_DOUBLE) {
795− for(; ref && btype == (ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
796− return !ref && nb_fields <= 4;
795+ if ((type->t & VT_BTYPE) == VT_STRUCT) {
796+ struct Sym* ref;
797+ int btype, nb_fields = 0;
798+
799+ ref = type->ref->next;
800+ btype = ref->type.t & VT_BTYPE;
801+ if (btype == VT_FLOAT || btype == VT_DOUBLE) {
802+ for (; ref && btype == (ref->type.t & VT_BTYPE);
803+ ref = ref->next, nb_fields++)
804+ ;
805+ return !ref && nb_fields <= 4;
806+ }
797807 }
798− }
799− return 0;
808+ return 0;
800809 }
801810
802811 struct avail_regs {
803− signed char avail[3]; /* 3 holes max with only float and double alignments */
804− int first_hole; /* first available hole */
805− int last_hole; /* last available hole (none if equal to first_hole) */
806− int first_free_reg; /* next free register in the sequence, hole excluded */
812+ signed char
813+ avail[3]; /* 3 holes max with only float and double alignments */
814+ int first_hole; /* first available hole */
815+ int last_hole; /* last available hole (none if equal to first_hole) */
816+ int first_free_reg; /* next free register in the sequence, hole excluded */
807817 };
808818
809819 #define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 }
@@ -817,40 +827,40 @@ struct avail_regs { · 7 unmodified lines
817827 avregs: opaque structure to keep track of available VFP co-processor regs
818828 align: alignment contraints for the param, as returned by type_size()
819829 size: size of the parameter, as returned by type_size() */
820−int assign_vfpreg(struct avail_regs *avregs, int align, int size)
830+int assign_vfpreg(struct avail_regs* avregs, int align, int size)
821831 {
822− int first_reg = 0;
823−
824− if (avregs->first_free_reg == -1)
832+ int first_reg = 0;
833+
834+ if (avregs->first_free_reg == -1)
835+ return -1;
836+ if (align >> 3) { /* double alignment */
837+ first_reg = avregs->first_free_reg;
838+ /* alignment contraint not respected so use next reg and record hole */
839+ if (first_reg & 1)
840+ avregs->avail[avregs->last_hole++] = first_reg++;
841+ } else { /* no special alignment (float or array of float) */
842+ /* if single float and a hole is available, assign the param to it */
843+ if (size == 4 && avregs->first_hole != avregs->last_hole)
844+ return avregs->avail[avregs->first_hole++];
845+ else
846+ first_reg = avregs->first_free_reg;
847+ }
848+ if (first_reg + size / 4 <= 16) {
849+ avregs->first_free_reg = first_reg + size / 4;
850+ return first_reg;
851+ }
852+ avregs->first_free_reg = -1;
825853 return -1;
826− if (align >> 3) { /* double alignment */
827− first_reg = avregs->first_free_reg;
828− /* alignment contraint not respected so use next reg and record hole */
829− if (first_reg & 1)
830− avregs->avail[avregs->last_hole++] = first_reg++;
831− } else { /* no special alignment (float or array of float) */
832− /* if single float and a hole is available, assign the param to it */
833− if (size == 4 && avregs->first_hole != avregs->last_hole)
834− return avregs->avail[avregs->first_hole++];
835− else
836− first_reg = avregs->first_free_reg;
837− }
838− if (first_reg + size / 4 <= 16) {
839− avregs->first_free_reg = first_reg + size / 4;
840− return first_reg;
841− }
842− avregs->first_free_reg = -1;
843− return -1;
844854 }
845855
846856 /* Returns whether all params need to be passed in core registers or not.
847857 This is the case for function part of the runtime ABI. */
848−int floats_in_core_regs(SValue *sval)
858+int floats_in_core_regs(SValue* sval)
849859 {
850− if (!sval->sym)
851− return 0;
860+ if (!sval->sym)
861+ return 0;
852862
853− switch (sval->sym->v) {
863+ switch (sval->sym->v) {
854864 case TOK___floatundisf:
855865 case TOK___floatundidf:
856866 case TOK___fixunssfdi:
@@ -862,34 +872,36 @@ int floats_in_core_regs(SValue *sval) · 5 unmodified lines
862872 case TOK___floatdidf:
863873 case TOK___fixsfdi:
864874 case TOK___fixdfdi:
865− return 1;
875+ return 1;
866876
867877 default:
868− return 0;
869− }
878+ return 0;
879+ }
870880 }
871881
872−ST_FUNC int regargs_nregs(RegArgs *args)
882+ST_FUNC int regargs_nregs(RegArgs* args)
873883 {
874884 return *args;
875885 }
876886
877887 /* Return the number of registers needed to return the struct, or 0 if
878888 returning via struct pointer. */
879−ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize, RegArgs *args) {
889+ST_FUNC int gfunc_sret(CType* vt, int variadic, CType* ret, int* ret_align,
890+ int* regsize, RegArgs* args)
891+{
880892 #ifdef TCC_ARM_EABI
881893 int size, align;
882894 size = type_size(vt, &align);
883895 if (float_abi == ARM_HARD_FLOAT && !variadic &&
884896 (is_float(vt->t) || is_hgen_float_aggr(vt))) {
885897 *ret_align = 8;
886− *regsize = 8;
898+ *regsize = 8;
887899 ret->ref = NULL;
888900 ret->t = VT_DOUBLE;
889901 *args = (size + 7) >> 3;
890902 } else if (size <= 4) {
891903 *ret_align = 4;
892− *regsize = 4;
904+ *regsize = 4;
893905 ret->ref = NULL;
894906 ret->t = VT_INT;
895907 *args = 1;
@@ -912,32 +924,33 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int · 16 unmodified lines
912924 - VFP_STRUCT_CLASS must come after VFP_CLASS.
913925 See the comment for the main loop in copy_params() for the reason. */
914926 enum reg_class {
915− STACK_CLASS = 0,
916− CORE_STRUCT_CLASS,
917− VFP_CLASS,
918− VFP_STRUCT_CLASS,
919− CORE_CLASS,
920− NB_CLASSES
927+ STACK_CLASS = 0,
928+ CORE_STRUCT_CLASS,
929+ VFP_CLASS,
930+ VFP_STRUCT_CLASS,
931+ CORE_CLASS,
932+ NB_CLASSES
921933 };
922934
923935 struct param_plan {
924− int start; /* first reg or addr used depending on the class */
925− int end; /* last reg used or next free addr depending on the class */
926− SValue *sval; /* pointer to SValue on the value stack */
927− struct param_plan *prev; /* previous element in this class */
936+ int start; /* first reg or addr used depending on the class */
937+ int end; /* last reg used or next free addr depending on the class */
938+ SValue* sval; /* pointer to SValue on the value stack */
939+ struct param_plan* prev; /* previous element in this class */
928940 };
929941
930942 struct plan {
931− struct param_plan *pplans; /* array of all the param plans */
932− struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */
943+ struct param_plan* pplans; /* array of all the param plans */
944+ struct param_plan*
945+ clsplans[NB_CLASSES]; /* per class lists of param plans */
933946 };
934947
935−#define add_param_plan(plan,pplan,class) \
936− do { \
937− pplan.prev = plan->clsplans[class]; \
938− plan->pplans[plan ## _nb] = pplan; \
939− plan->clsplans[class] = &plan->pplans[plan ## _nb++]; \
940− } while(0)
948+#define add_param_plan(plan, pplan, class) \
949+ do { \
950+ pplan.prev = plan->clsplans[class]; \
951+ plan->pplans[plan##_nb] = pplan; \
952+ plan->clsplans[class] = &plan->pplans[plan##_nb++]; \
953+ } while (0)
941954
942955 /* Assign parameters to registers and stack with alignment according to the
943956 rules in the procedure call standard for the ARM architecture (AAPCS).
@@ -956,90 +969,93 @@ struct plan { · 12 unmodified lines
956969 Note: this function allocated an array in plan->pplans with tcc_malloc. It
957970 is the responsibility of the caller to free this array once used (ie not
958971 before copy_params). */
959−static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
972+static int assign_regs(int nb_args, int float_abi, struct plan* plan, int* todo)
960973 {
961− int i, size, align;
962− int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
963− int plan_nb = 0;
964− struct param_plan pplan;
965− struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
966−
967− ncrn = nsaa = 0;
968− *todo = 0;
969− plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
970− memset(plan->clsplans, 0, sizeof(plan->clsplans));
971− for(i = nb_args; i-- ;) {
972− int j, start_vfpreg = 0;
973− CType type = vtop[-i].type;
974− type.t &= ~VT_ARRAY;
975− size = type_size(&type, &align);
976− size = (size + 3) & ~3;
977− align = (align + 3) & ~3;
978− switch(vtop[-i].type.t & VT_BTYPE) {
979− case VT_STRUCT:
980− case VT_FLOAT:
981− case VT_DOUBLE:
982− case VT_LDOUBLE:
983− if (float_abi == ARM_HARD_FLOAT) {
984− int is_hfa = 0; /* Homogeneous float aggregate */
985−
986− if (is_float(vtop[-i].type.t)
987− || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
988− int end_vfpreg;
989−
990− start_vfpreg = assign_vfpreg(&avregs, align, size);
991− end_vfpreg = start_vfpreg + ((size - 1) >> 2);
992− if (start_vfpreg >= 0) {
993− pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]};
994− if (is_hfa)
995− add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
996− else
997− add_param_plan(plan, pplan, VFP_CLASS);
974+ int i, size, align;
975+ int ncrn /* next core register number */,
976+ nsaa /* next stacked argument address*/;
977+ int plan_nb = 0;
978+ struct param_plan pplan;
979+ struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
980+
981+ ncrn = nsaa = 0;
982+ *todo = 0;
983+ plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
984+ memset(plan->clsplans, 0, sizeof(plan->clsplans));
985+ for (i = nb_args; i--;) {
986+ int j, start_vfpreg = 0;
987+ CType type = vtop[-i].type;
988+ type.t &= ~VT_ARRAY;
989+ size = type_size(&type, &align);
990+ size = (size + 3) & ~3;
991+ align = (align + 3) & ~3;
992+ switch (vtop[-i].type.t & VT_BTYPE) {
993+ case VT_STRUCT:
994+ case VT_FLOAT:
995+ case VT_DOUBLE:
996+ case VT_LDOUBLE:
997+ if (float_abi == ARM_HARD_FLOAT) {
998+ int is_hfa = 0; /* Homogeneous float aggregate */
999+
1000+ if (is_float(vtop[-i].type.t) ||
1001+ (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
1002+ int end_vfpreg;
1003+
1004+ start_vfpreg = assign_vfpreg(&avregs, align, size);
1005+ end_vfpreg = start_vfpreg + ((size - 1) >> 2);
1006+ if (start_vfpreg >= 0) {
1007+ pplan = (struct param_plan){start_vfpreg, end_vfpreg,
1008+ &vtop[-i]};
1009+ if (is_hfa)
1010+ add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
1011+ else
1012+ add_param_plan(plan, pplan, VFP_CLASS);
1013+ continue;
1014+ } else
1015+ break;
1016+ }
1017+ }
1018+ ncrn = (ncrn + (align - 1) / 4) & ~((align / 4) - 1);
1019+ if (ncrn + size / 4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
1020+ /* The parameter is allocated both in core register and on
1021+ * stack. As
1022+ * such, it can be of either class: it would either be the last of
1023+ * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
1024+ for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
1025+ *todo |= (1 << j);
1026+ pplan = (struct param_plan){ncrn, j, &vtop[-i]};
1027+ add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
1028+ ncrn += size / 4;
1029+ if (ncrn > 4)
1030+ nsaa = (ncrn - 4) * 4;
1031+ } else {
1032+ ncrn = 4;
1033+ break;
1034+ }
9981035 continue;
999− } else
1000− break;
1001− }
1002− }
1003− ncrn = (ncrn + (align-1)/4) & ~((align/4) - 1);
1004− if (ncrn + size/4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
1005− /* The parameter is allocated both in core register and on stack. As
1006− * such, it can be of either class: it would either be the last of
1007− * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
1008− for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
1009− *todo|=(1<<j);
1010− pplan = (struct param_plan) {ncrn, j, &vtop[-i]};
1011− add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
1012− ncrn += size/4;
1013− if (ncrn > 4)
1014− nsaa = (ncrn - 4) * 4;
1015− } else {
1016− ncrn = 4;
1017− break;
1018− }
1019− continue;
1020− default:
1021− if (ncrn < 4) {
1022− int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
1023−
1024− if (is_long) {
1025− ncrn = (ncrn + 1) & -2;
1026− if (ncrn == 4)
1027− break;
1036+ default:
1037+ if (ncrn < 4) {
1038+ int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
1039+
1040+ if (is_long) {
1041+ ncrn = (ncrn + 1) & -2;
1042+ if (ncrn == 4)
1043+ break;
1044+ }
1045+ pplan = (struct param_plan){ncrn, ncrn, &vtop[-i]};
1046+ ncrn++;
1047+ if (is_long)
1048+ pplan.end = ncrn++;
1049+ add_param_plan(plan, pplan, CORE_CLASS);
1050+ continue;
1051+ }
10281052 }
1029− pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]};
1030− ncrn++;
1031− if (is_long)
1032− pplan.end = ncrn++;
1033− add_param_plan(plan, pplan, CORE_CLASS);
1034− continue;
1035− }
1053+ nsaa = (nsaa + (align - 1)) & ~(align - 1);
1054+ pplan = (struct param_plan){nsaa, nsaa + size, &vtop[-i]};
1055+ add_param_plan(plan, pplan, STACK_CLASS);
1056+ nsaa += size; /* size already rounded up before */
10361057 }
1037− nsaa = (nsaa + (align - 1)) & ~(align - 1);
1038− pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]};
1039− add_param_plan(plan, pplan, STACK_CLASS);
1040− nsaa += size; /* size already rounded up before */
1041− }
1042− return nsaa;
1058+ return nsaa;
10431059 }
10441060
10451061 #undef add_param_plan
@@ -1052,156 +1068,165 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 6 unmodified lines
10521068 todo: a bitmap indicating what core reg will hold a parameter
10531069
10541070 Returns the number of SValue added by this function on the value stack */
1055−static int copy_params(int nb_args, struct plan *plan, int todo)
1071+static int copy_params(int nb_args, struct plan* plan, int todo)
10561072 {
1057− int size, align, r, i, nb_extra_sval = 0;
1058− struct param_plan *pplan;
1059−
1060− /* Several constraints require parameters to be copied in a specific order:
1061− - structures are copied to the stack before being loaded in a reg;
1062− - floats loaded to an odd numbered VFP reg are first copied to the
1063− preceding even numbered VFP reg and then moved to the next VFP reg.
1064−
1065− It is thus important that:
1066− - structures assigned to core regs must be copied after parameters
1067− assigned to the stack but before structures assigned to VFP regs because
1068− a structure can lie partly in core registers and partly on the stack;
1069− - parameters assigned to the stack and all structures be copied before
1070− parameters assigned to a core reg since copying a parameter to the stack
1071− require using a core reg;
1072− - parameters assigned to VFP regs be copied before structures assigned to
1073− VFP regs as the copy might use an even numbered VFP reg that already
1074− holds part of a structure. */
1075− for(i = 0; i < NB_CLASSES; i++) {
1076− for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
1077− vpushv(pplan->sval);
1078− pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
1079− switch(i) {
1080− case STACK_CLASS:
1081− case CORE_STRUCT_CLASS:
1082− case VFP_STRUCT_CLASS:
1083− if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
1084− int padding = 0;
1085− size = type_size(&pplan->sval->type, &align);
1086− /* align to stack align size */
1087− size = (size + 3) & ~3;
1088− if (i == STACK_CLASS && pplan->prev)
1089− padding = pplan->start - pplan->prev->end;
1090− size += padding; /* Add padding if any */
1091− /* allocate the necessary size on stack */
1092− gadd_sp(-size);
1093− /* generate structure store */
1094− r = get_reg(RC_INT);
1095− o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
1096− vset(&vtop->type, r | VT_LVAL, 0);
1097− vswap();
1098− vstore(); /* memcpy to current sp + potential padding */
1099−
1100− /* Homogeneous float aggregate are loaded to VFP registers
1101− immediately since there is no way of loading data in multiple
1102− non consecutive VFP registers as what is done for other
1103− structures (see the use of todo). */
1104− if (i == VFP_STRUCT_CLASS) {
1105− int first = pplan->start, nb = pplan->end - first + 1;
1106− /* vpop.32 {pplan->start, ..., pplan->end} */
1107− o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
1108− /* No need to write the register used to a SValue since VFP regs
1109− cannot be used for gcall_or_jmp */
1110− }
1111− } else {
1112− if (is_float(pplan->sval->type.t)) {
1073+ int size, align, r, i, nb_extra_sval = 0;
1074+ struct param_plan* pplan;
1075+
1076+ /* Several constraints require parameters to be copied in a specific order:
1077+ - structures are copied to the stack before being loaded in a reg;
1078+ - floats loaded to an odd numbered VFP reg are first copied to the
1079+ preceding even numbered VFP reg and then moved to the next VFP reg.
1080+
1081+ It is thus important that:
1082+ - structures assigned to core regs must be copied after parameters
1083+ assigned to the stack but before structures assigned to VFP regs
1084+ because a structure can lie partly in core registers and partly on
1085+ the stack;
1086+ - parameters assigned to the stack and all structures be copied before
1087+ parameters assigned to a core reg since copying a parameter to the
1088+ stack require using a core reg;
1089+ - parameters assigned to VFP regs be copied before structures assigned to
1090+ VFP regs as the copy might use an even numbered VFP reg that already
1091+ holds part of a structure. */
1092+ for (i = 0; i < NB_CLASSES; i++) {
1093+ for (pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
1094+ vpushv(pplan->sval);
1095+ pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
1096+ switch (i) {
1097+ case STACK_CLASS:
1098+ case CORE_STRUCT_CLASS:
1099+ case VFP_STRUCT_CLASS:
1100+ if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
1101+ int padding = 0;
1102+ size = type_size(&pplan->sval->type, &align);
1103+ /* align to stack align size */
1104+ size = (size + 3) & ~3;
1105+ if (i == STACK_CLASS && pplan->prev)
1106+ padding = pplan->start - pplan->prev->end;
1107+ size += padding; /* Add padding if any */
1108+ /* allocate the necessary size on stack */
1109+ gadd_sp(-size);
1110+ /* generate structure store */
1111+ r = get_reg(RC_INT);
1112+ o(0xE28D0000 | (intr(r) << 12) |
1113+ padding); /* add r, sp, padding */
1114+ vset(&vtop->type, r | VT_LVAL, 0);
1115+ vswap();
1116+ vstore(); /* memcpy to current sp + potential padding */
1117+
1118+ /* Homogeneous float aggregate are loaded to VFP registers
1119+ immediately since there is no way of loading data in
1120+ multiple non consecutive VFP registers as what is done
1121+ for other structures (see the use of todo). */
1122+ if (i == VFP_STRUCT_CLASS) {
1123+ int first = pplan->start, nb = pplan->end - first + 1;
1124+ /* vpop.32 {pplan->start, ..., pplan->end} */
1125+ o(0xECBD0A00 | (first & 1) << 22 | (first >> 1) << 12 |
1126+ nb);
1127+ /* No need to write the register used to a SValue since
1128+ VFP regs cannot be used for gcall_or_jmp */
1129+ }
1130+ } else {
1131+ if (is_float(pplan->sval->type.t)) {
11131132 #ifdef TCC_ARM_VFP
1114− r = vfpr(gv(RC_FLOAT)) << 12;
1115− if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1116− size = 4;
1117− else {
1118− size = 8;
1119− r |= 0x101; /* vpush.32 -> vpush.64 */
1120− }
1121− o(0xED2D0A01 + r); /* vpush */
1133+ r = vfpr(gv(RC_FLOAT)) << 12;
1134+ if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1135+ size = 4;
1136+ else {
1137+ size = 8;
1138+ r |= 0x101; /* vpush.32 -> vpush.64 */
1139+ }
1140+ o(0xED2D0A01 + r); /* vpush */
11221141 #else
1123− r = fpr(gv(RC_FLOAT)) << 12;
1124− if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1125− size = 4;
1126− else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
1127− size = 8;
1128− else
1129− size = LDOUBLE_SIZE;
1130−
1131− if (size == 12)
1132− r |= 0x400000;
1133− else if(size == 8)
1134− r|=0x8000;
1135−
1136− o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
1142+ r = fpr(gv(RC_FLOAT)) << 12;
1143+ if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1144+ size = 4;
1145+ else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
1146+ size = 8;
1147+ else
1148+ size = LDOUBLE_SIZE;
1149+
1150+ if (size == 12)
1151+ r |= 0x400000;
1152+ else if (size == 8)
1153+ r |= 0x8000;
1154+
1155+ o(0xED2D0100 | r | (size >> 2)); /* some kind of vpush for FPA */
11371156 #endif
1138− } else {
1139− /* simple type (currently always same size) */
1140− /* XXX: implicit cast ? */
1141− size=4;
1142− if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1143− lexpand_nr();
1144− size = 8;
1145− r = gv(RC_INT);
1146− o(0xE52D0004|(intr(r)<<12)); /* push r */
1147− vtop--;
1148− }
1149− r = gv(RC_INT);
1150− o(0xE52D0004|(intr(r)<<12)); /* push r */
1157+ } else {
1158+ /* simple type (currently always same size) */
1159+ /* XXX: implicit cast ? */
1160+ size = 4;
1161+ if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1162+ lexpand_nr();
1163+ size = 8;
1164+ r = gv(RC_INT);
1165+ o(0xE52D0004 | (intr(r) << 12)); /* push r */
1166+ vtop--;
1167+ }
1168+ r = gv(RC_INT);
1169+ o(0xE52D0004 | (intr(r) << 12)); /* push r */
1170+ }
1171+ if (i == STACK_CLASS && pplan->prev)
1172+ gadd_sp(pplan->prev->end -
1173+ pplan->start); /* Add padding if any */
1174+ }
1175+ break;
1176+
1177+ case VFP_CLASS:
1178+ gv(regmask(TREG_F0 + (pplan->start >> 1)));
1179+ if (pplan->start &
1180+ 1) { /* Must be in upper part of double register */
1181+ o(0xEEF00A40 | ((pplan->start >> 1) << 12) |
1182+ (pplan->start >> 1)); /* vmov.f32 s(n+1), sn */
1183+ vtop->r =
1184+ VT_CONST; /* avoid being saved on stack by gv for next
1185+ float */
1186+ }
1187+ break;
1188+
1189+ case CORE_CLASS:
1190+ if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1191+ lexpand_nr();
1192+ gv(regmask(pplan->end));
1193+ pplan->sval->r2 = vtop->r;
1194+ vtop--;
1195+ }
1196+ gv(regmask(pplan->start));
1197+ /* Mark register as used so that gcall_or_jmp use another one
1198+ (regs >=4 are free as never used to pass parameters) */
1199+ pplan->sval->r = vtop->r;
1200+ break;
11511201 }
1152− if (i == STACK_CLASS && pplan->prev)
1153− gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
1154− }
1155− break;
1156−
1157− case VFP_CLASS:
1158− gv(regmask(TREG_F0 + (pplan->start >> 1)));
1159− if (pplan->start & 1) { /* Must be in upper part of double register */
1160− o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
1161− vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
1162− }
1163− break;
1164−
1165− case CORE_CLASS:
1166− if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1167− lexpand_nr();
1168− gv(regmask(pplan->end));
1169− pplan->sval->r2 = vtop->r;
11701202 vtop--;
1171− }
1172− gv(regmask(pplan->start));
1173− /* Mark register as used so that gcall_or_jmp use another one
1174− (regs >=4 are free as never used to pass parameters) */
1175− pplan->sval->r = vtop->r;
1176− break;
1177− }
1178− vtop--;
1203+ }
11791204 }
1180− }
1181−
1182− /* Manually free remaining registers since next parameters are loaded
1183− * manually, without the help of gv(int). */
1184− save_regs(nb_args);
1185−
1186− if(todo) {
1187− o(0xE8BD0000|todo); /* pop {todo} */
1188− for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
1189− int r;
1190− pplan->sval->r = pplan->start;
1191− /* An SValue can only pin 2 registers at best (r and r2) but a structure
1192− can occupy more than 2 registers. Thus, we need to push on the value
1193− stack some fake parameter to have on SValue for each registers used
1194− by a structure (r2 is not used). */
1195− for (r = pplan->start + 1; r <= pplan->end; r++) {
1196− if (todo & (1 << r)) {
1197− nb_extra_sval++;
1198− vpushi(0);
1199− vtop->r = r;
1205+
1206+ /* Manually free remaining registers since next parameters are loaded
1207+ * manually, without the help of gv(int). */
1208+ save_regs(nb_args);
1209+
1210+ if (todo) {
1211+ o(0xE8BD0000 | todo); /* pop {todo} */
1212+ for (pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan;
1213+ pplan = pplan->prev) {
1214+ int r;
1215+ pplan->sval->r = pplan->start;
1216+ /* An SValue can only pin 2 registers at best (r and r2) but a
1217+ structure can occupy more than 2 registers. Thus, we need to
1218+ push on the value stack some fake parameter to have on SValue
1219+ for each registers used by a structure (r2 is not used). */
1220+ for (r = pplan->start + 1; r <= pplan->end; r++) {
1221+ if (todo & (1 << r)) {
1222+ nb_extra_sval++;
1223+ vpushi(0);
1224+ vtop->r = r;
1225+ }
1226+ }
12001227 }
1201− }
12021228 }
1203− }
1204− return nb_extra_sval;
1229+ return nb_extra_sval;
12051230 }
12061231
12071232 /* Generate function call. The function address is pushed first, then
@@ -1209,733 +1234,738 @@ static int copy_params(int nb_args, struct plan *plan, int todo) · 1 unmodified line
12091234 parameters and the function address. */
12101235 void gfunc_call(int nb_args)
12111236 {
1212− int r, args_size;
1213− int def_float_abi = float_abi;
1214− int todo;
1215− struct plan plan;
1237+ int r, args_size;
1238+ int def_float_abi = float_abi;
1239+ int todo;
1240+ struct plan plan;
12161241
12171242 #ifdef TCC_ARM_EABI
1218− int variadic;
1243+ int variadic;
12191244
1220− if (float_abi == ARM_HARD_FLOAT) {
1221− variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS);
1222− if (variadic || floats_in_core_regs(&vtop[-nb_args]))
1223− float_abi = ARM_SOFTFP_FLOAT;
1224− }
1245+ if (float_abi == ARM_HARD_FLOAT) {
1246+ variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS);
1247+ if (variadic || floats_in_core_regs(&vtop[-nb_args]))
1248+ float_abi = ARM_SOFTFP_FLOAT;
1249+ }
12251250 #endif
1226− /* cannot let cpu flags if other instruction are generated. Also avoid leaving
1227− VT_JMP anywhere except on the top of the stack because it would complicate
1228− the code generator. */
1229− r = vtop->r & VT_VALMASK;
1230− if (r == VT_CMP || (r & ~1) == VT_JMP)
1231− gv(RC_INT);
1251+ /* cannot let cpu flags if other instruction are generated. Also avoid
1252+ leaving VT_JMP anywhere except on the top of the stack because it
1253+ would complicate the code generator. */
1254+ r = vtop->r & VT_VALMASK;
1255+ if (r == VT_CMP || (r & ~1) == VT_JMP)
1256+ gv(RC_INT);
12321257
1233− args_size = assign_regs(nb_args, float_abi, &plan, &todo);
1258+ args_size = assign_regs(nb_args, float_abi, &plan, &todo);
12341259
12351260 #ifdef TCC_ARM_EABI
1236− if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
1237− args_size = (args_size + 7) & ~7;
1238− o(0xE24DD004); /* sub sp, sp, #4 */
1239− }
1261+ if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
1262+ args_size = (args_size + 7) & ~7;
1263+ o(0xE24DD004); /* sub sp, sp, #4 */
1264+ }
12401265 #endif
12411266
1242− nb_args += copy_params(nb_args, &plan, todo);
1243− tcc_free(plan.pplans);
1267+ nb_args += copy_params(nb_args, &plan, todo);
1268+ tcc_free(plan.pplans);
12441269
1245− /* Move fct SValue on top as required by gcall_or_jmp */
1246− vrotb(nb_args + 1);
1247− gcall_or_jmp(0);
1248− if (args_size)
1249− gadd_sp(args_size); /* pop all parameters passed on the stack */
1270+ /* Move fct SValue on top as required by gcall_or_jmp */
1271+ vrotb(nb_args + 1);
1272+ gcall_or_jmp(0);
1273+ if (args_size)
1274+ gadd_sp(args_size); /* pop all parameters passed on the stack */
12501275 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
1251− if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
1252− if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
1253− o(0xEE000A10); /*vmov s0, r0 */
1254− } else {
1255− o(0xEE000B10); /* vmov.32 d0[0], r0 */
1256− o(0xEE201B10); /* vmov.32 d0[1], r1 */
1276+ if (float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
1277+ if ((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
1278+ o(0xEE000A10); /*vmov s0, r0 */
1279+ } else {
1280+ o(0xEE000B10); /* vmov.32 d0[0], r0 */
1281+ o(0xEE201B10); /* vmov.32 d0[1], r1 */
1282+ }
12571283 }
1258− }
12591284 #endif
1260− vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
1261− leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
1262− float_abi = def_float_abi;
1285+ vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
1286+ leaffunc =
1287+ 0; /* we are calling a function, so we aren't in a leaf function */
1288+ float_abi = def_float_abi;
12631289 }
12641290
12651291 /* generate function prolog of type 't' */
1266−void gfunc_prolog(CType *func_type)
1292+void gfunc_prolog(CType* func_type)
12671293 {
1268− Sym *sym,*sym2;
1269− int n, nf, size, align, rs, struct_ret = 0;
1270− int addr, pn, sn; /* pn=core, sn=stack */
1271− CType ret_type;
1272− RegArgs dummy;
1294+ Sym* sym, *sym2;
1295+ int n, nf, size, align, rs, struct_ret = 0;
1296+ int addr, pn, sn; /* pn=core, sn=stack */
1297+ CType ret_type;
1298+ RegArgs dummy;
12731299
12741300 #ifdef TCC_ARM_EABI
1275− struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
1301+ struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
12761302 #endif
12771303
1278− sym = func_type->ref;
1279− func_vt = sym->type;
1280− func_var = (func_type->ref->c == FUNC_ELLIPSIS);
1281−
1282− n = nf = 0;
1283− if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
1284− !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs, &dummy))
1285− {
1286− n++;
1287− struct_ret = 1;
1288− func_vc = 12; /* Offset from fp of the place to store the result */
1289− }
1290− for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
1291− size = type_size(&sym2->type, &align);
1304+ sym = func_type->ref;
1305+ func_vt = sym->type;
1306+ func_var = (func_type->ref->c == FUNC_ELLIPSIS);
1307+
1308+ n = nf = 0;
1309+ if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
1310+ !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs, &dummy)) {
1311+ n++;
1312+ struct_ret = 1;
1313+ func_vc = 12; /* Offset from fp of the place to store the result */
1314+ }
1315+ for (sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
1316+ size = type_size(&sym2->type, &align);
12921317 #ifdef TCC_ARM_EABI
1293− if (float_abi == ARM_HARD_FLOAT && !func_var &&
1294− (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
1295− int tmpnf = assign_vfpreg(&avregs, align, size);
1296− tmpnf += (size + 3) / 4;
1297− nf = (tmpnf > nf) ? tmpnf : nf;
1298− } else
1318+ if (float_abi == ARM_HARD_FLOAT && !func_var &&
1319+ (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
1320+ int tmpnf = assign_vfpreg(&avregs, align, size);
1321+ tmpnf += (size + 3) / 4;
1322+ nf = (tmpnf > nf) ? tmpnf : nf;
1323+ } else
12991324 #endif
1300− if (n < 4)
1301− n += (size + 3) / 4;
1302− }
1303− o(0xE1A0C00D); /* mov ip,sp */
1304− if (func_var)
1305− n=4;
1306− if (n) {
1307− if(n>4)
1308− n=4;
1325+ if (n < 4)
1326+ n += (size + 3) / 4;
1327+ }
1328+ o(0xE1A0C00D); /* mov ip,sp */
1329+ if (func_var)
1330+ n = 4;
1331+ if (n) {
1332+ if (n > 4)
1333+ n = 4;
13091334 #ifdef TCC_ARM_EABI
1310− n=(n+1)&-2;
1335+ n = (n + 1) & -2;
13111336 #endif
1312− o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
1313− }
1314− if (nf) {
1315− if (nf>16)
1316− nf=16;
1317− nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */
1318− o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */
1319− }
1320− o(0xE92D5800); /* save fp, ip, lr */
1321− o(0xE1A0B00D); /* mov fp, sp */
1322− func_sub_sp_offset = ind;
1323− o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
1337+ o(0xE92D0000 | ((1 << n) - 1)); /* save r0-r4 on stack if needed */
1338+ }
1339+ if (nf) {
1340+ if (nf > 16)
1341+ nf = 16;
1342+ nf = (nf + 1) & -2; /* nf => HARDFLOAT => EABI */
1343+ o(0xED2D0A00 | nf); /* save s0-s15 on stack if needed */
1344+ }
1345+ o(0xE92D5800); /* save fp, ip, lr */
1346+ o(0xE1A0B00D); /* mov fp, sp */
1347+ func_sub_sp_offset = ind;
1348+ o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
13241349
13251350 #ifdef TCC_ARM_EABI
1326− if (float_abi == ARM_HARD_FLOAT) {
1327− func_vc += nf * 4;
1328− avregs = AVAIL_REGS_INITIALIZER;
1329− }
1351+ if (float_abi == ARM_HARD_FLOAT) {
1352+ func_vc += nf * 4;
1353+ avregs = AVAIL_REGS_INITIALIZER;
1354+ }
13301355 #endif
1331− pn = struct_ret, sn = 0;
1332− while ((sym = sym->next)) {
1333− CType *type;
1334− type = &sym->type;
1335− size = type_size(type, &align);
1336− size = (size + 3) >> 2;
1337− align = (align + 3) & ~3;
1356+ pn = struct_ret, sn = 0;
1357+ while ((sym = sym->next)) {
1358+ CType* type;
1359+ type = &sym->type;
1360+ size = type_size(type, &align);
1361+ size = (size + 3) >> 2;
1362+ align = (align + 3) & ~3;
13381363 #ifdef TCC_ARM_EABI
1339− if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
1340− || is_hgen_float_aggr(&sym->type))) {
1341− int fpn = assign_vfpreg(&avregs, align, size << 2);
1342− if (fpn >= 0)
1343− addr = fpn * 4;
1344− else
1345− goto from_stack;
1346− } else
1364+ if (float_abi == ARM_HARD_FLOAT && !func_var &&
1365+ (is_float(sym->type.t) || is_hgen_float_aggr(&sym->type))) {
1366+ int fpn = assign_vfpreg(&avregs, align, size << 2);
1367+ if (fpn >= 0)
1368+ addr = fpn * 4;
1369+ else
1370+ goto from_stack;
1371+ } else
13471372 #endif
1348− if (pn < 4) {
1373+ if (pn < 4) {
13491374 #ifdef TCC_ARM_EABI
1350− pn = (pn + (align-1)/4) & -(align/4);
1375+ pn = (pn + (align - 1) / 4) & -(align / 4);
13511376 #endif
1352− addr = (nf + pn) * 4;
1353− pn += size;
1354− if (!sn && pn > 4)
1355− sn = (pn - 4);
1356− } else {
1377+ addr = (nf + pn) * 4;
1378+ pn += size;
1379+ if (!sn && pn > 4)
1380+ sn = (pn - 4);
1381+ } else {
13571382 #ifdef TCC_ARM_EABI
1358−from_stack:
1359− sn = (sn + (align-1)/4) & -(align/4);
1383+ from_stack:
1384+ sn = (sn + (align - 1) / 4) & -(align / 4);
13601385 #endif
1361− addr = (n + nf + sn) * 4;
1362− sn += size;
1386+ addr = (n + nf + sn) * 4;
1387+ sn += size;
1388+ }
1389+ sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
1390+ addr + 12);
13631391 }
1364− sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
1365− addr + 12);
1366− }
1367− last_itod_magic=0;
1368− leaffunc = 1;
1369− loc = 0;
1392+ last_itod_magic = 0;
1393+ leaffunc = 1;
1394+ loc = 0;
13701395 }
13711396
13721397 /* generate function epilog */
13731398 void gfunc_epilog(void)
13741399 {
1375− uint32_t x;
1376− int diff;
1377− /* Copy float return value to core register if base standard is used and
1378− float computation is made with VFP */
1400+ uint32_t x;
1401+ int diff;
1402+/* Copy float return value to core register if base standard is used and
1403+ float computation is made with VFP */
13791404 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
1380− if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
1381− if((func_vt.t & VT_BTYPE) == VT_FLOAT)
1382− o(0xEE100A10); /* fmrs r0, s0 */
1383− else {
1384− o(0xEE100B10); /* fmrdl r0, d0 */
1385− o(0xEE301B10); /* fmrdh r1, d0 */
1405+ if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
1406+ if ((func_vt.t & VT_BTYPE) == VT_FLOAT)
1407+ o(0xEE100A10); /* fmrs r0, s0 */
1408+ else {
1409+ o(0xEE100B10); /* fmrdl r0, d0 */
1410+ o(0xEE301B10); /* fmrdh r1, d0 */
1411+ }
13861412 }
1387− }
13881413 #endif
1389− o(0xE89BA800); /* restore fp, sp, pc */
1390− diff = (-loc + 3) & -4;
1414+ o(0xE89BA800); /* restore fp, sp, pc */
1415+ diff = (-loc + 3) & -4;
13911416 #ifdef TCC_ARM_EABI
1392− if(!leaffunc)
1393− diff = ((diff + 11) & -8) - 4;
1417+ if (!leaffunc)
1418+ diff = ((diff + 11) & -8) - 4;
13941419 #endif
1395− if(diff > 0) {
1396− x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
1397− if(x)
1398− *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
1399− else {
1400− int addr;
1401− addr=ind;
1402− o(0xE59FC004); /* ldr ip,[pc+4] */
1403− o(0xE04BD00C); /* sub sp,fp,ip */
1404− o(0xE1A0F00E); /* mov pc,lr */
1405− o(diff);
1406− *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
1420+ if (diff > 0) {
1421+ x = stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
1422+ if (x)
1423+ *(uint32_t*)(cur_text_section->data + func_sub_sp_offset) = x;
1424+ else {
1425+ int addr;
1426+ addr = ind;
1427+ o(0xE59FC004); /* ldr ip,[pc+4] */
1428+ o(0xE04BD00C); /* sub sp,fp,ip */
1429+ o(0xE1A0F00E); /* mov pc,lr */
1430+ o(diff);
1431+ *(uint32_t*)(cur_text_section->data + func_sub_sp_offset) =
1432+ 0xE1000000 | encbranch(func_sub_sp_offset, addr, 1);
1433+ }
14071434 }
1408− }
14091435 }
14101436
14111437 /* generate a jump to a label */
14121438 int gjmp(int t)
14131439 {
1414− int r;
1415− r=ind;
1416− o(0xE0000000|encbranch(r,t,1));
1417− return r;
1440+ int r;
1441+ r = ind;
1442+ o(0xE0000000 | encbranch(r, t, 1));
1443+ return r;
14181444 }
14191445
14201446 /* generate a jump to a fixed address */
14211447 void gjmp_addr(int a)
14221448 {
1423− gjmp(a);
1449+ gjmp(a);
14241450 }
14251451
14261452 /* generate a test. set 'inv' to invert test. Stack entry is popped */
14271453 int gtst(int inv, int t)
14281454 {
1429− int v, r;
1430− uint32_t op;
1431− v = vtop->r & VT_VALMASK;
1432− r=ind;
1433− if (v == VT_CMP) {
1434− op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
1435− op|=encbranch(r,t,1);
1436− o(op);
1437− t=r;
1438− } else if (v == VT_JMP || v == VT_JMPI) {
1439− if ((v & 1) == inv) {
1440− if(!vtop->c.i)
1441− vtop->c.i=t;
1442− else {
1443− uint32_t *x;
1444− int p,lp;
1445− if(t) {
1446− p = vtop->c.i;
1447− do {
1448− p = decbranch(lp=p);
1449− } while(p);
1450− x = (uint32_t *)(cur_text_section->data + lp);
1451− *x &= 0xff000000;
1452− *x |= encbranch(lp,t,1);
1453− }
1454− t = vtop->c.i;
1455− }
1456− } else {
1457− t = gjmp(t);
1458− gsym(vtop->c.i);
1455+ int v, r;
1456+ uint32_t op;
1457+ v = vtop->r & VT_VALMASK;
1458+ r = ind;
1459+ if (v == VT_CMP) {
1460+ op = mapcc(inv ? negcc(vtop->c.i) : vtop->c.i);
1461+ op |= encbranch(r, t, 1);
1462+ o(op);
1463+ t = r;
1464+ } else if (v == VT_JMP || v == VT_JMPI) {
1465+ if ((v & 1) == inv) {
1466+ if (!vtop->c.i)
1467+ vtop->c.i = t;
1468+ else {
1469+ uint32_t* x;
1470+ int p, lp;
1471+ if (t) {
1472+ p = vtop->c.i;
1473+ do {
1474+ p = decbranch(lp = p);
1475+ } while (p);
1476+ x = (uint32_t*)(cur_text_section->data + lp);
1477+ *x &= 0xff000000;
1478+ *x |= encbranch(lp, t, 1);
1479+ }
1480+ t = vtop->c.i;
1481+ }
1482+ } else {
1483+ t = gjmp(t);
1484+ gsym(vtop->c.i);
1485+ }
14591486 }
1460− }
1461− vtop--;
1462− return t;
1487+ vtop--;
1488+ return t;
14631489 }
14641490
14651491 /* generate an integer binary operation */
14661492 void gen_opi(int op)
14671493 {
1468− int c, func = 0;
1469− uint32_t opc = 0, r, fr;
1470− unsigned short retreg = REG_IRET;
1494+ int c, func = 0;
1495+ uint32_t opc = 0, r, fr;
1496+ unsigned short retreg = REG_IRET;
14711497
1472− c=0;
1473− switch(op) {
1498+ c = 0;
1499+ switch (op) {
14741500 case '+':
1475− opc = 0x8;
1476− c=1;
1477− break;
1501+ opc = 0x8;
1502+ c = 1;
1503+ break;
14781504 case TOK_ADDC1: /* add with carry generation */
1479− opc = 0x9;
1480− c=1;
1481− break;
1505+ opc = 0x9;
1506+ c = 1;
1507+ break;
14821508 case '-':
1483− opc = 0x4;
1484− c=1;
1485− break;
1509+ opc = 0x4;
1510+ c = 1;
1511+ break;
14861512 case TOK_SUBC1: /* sub with carry generation */
1487− opc = 0x5;
1488− c=1;
1489− break;
1513+ opc = 0x5;
1514+ c = 1;
1515+ break;
14901516 case TOK_ADDC2: /* add with carry use */
1491− opc = 0xA;
1492− c=1;
1493− break;
1517+ opc = 0xA;
1518+ c = 1;
1519+ break;
14941520 case TOK_SUBC2: /* sub with carry use */
1495− opc = 0xC;
1496− c=1;
1497− break;
1521+ opc = 0xC;
1522+ c = 1;
1523+ break;
14981524 case '&':
1499− opc = 0x0;
1500− c=1;
1501− break;
1525+ opc = 0x0;
1526+ c = 1;
1527+ break;
15021528 case '^':
1503− opc = 0x2;
1504− c=1;
1505− break;
1529+ opc = 0x2;
1530+ c = 1;
1531+ break;
15061532 case '|':
1507− opc = 0x18;
1508− c=1;
1509− break;
1533+ opc = 0x18;
1534+ c = 1;
1535+ break;
15101536 case '*':
1511− gv2(RC_INT, RC_INT);
1512− r = vtop[-1].r;
1513− fr = vtop[0].r;
1514− vtop--;
1515− o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
1516− return;
1537+ gv2(RC_INT, RC_INT);
1538+ r = vtop[-1].r;
1539+ fr = vtop[0].r;
1540+ vtop--;
1541+ o(0xE0000090 | (intr(r) << 16) | (intr(r) << 8) | intr(fr));
1542+ return;
15171543 case TOK_SHL:
1518− opc = 0;
1519− c=2;
1520− break;
1544+ opc = 0;
1545+ c = 2;
1546+ break;
15211547 case TOK_SHR:
1522− opc = 1;
1523− c=2;
1524− break;
1548+ opc = 1;
1549+ c = 2;
1550+ break;
15251551 case TOK_SAR:
1526− opc = 2;
1527− c=2;
1528− break;
1552+ opc = 2;
1553+ c = 2;
1554+ break;
15291555 case '/':
15301556 case TOK_PDIV:
1531− func=TOK___divsi3;
1532− c=3;
1533− break;
1557+ func = TOK___divsi3;
1558+ c = 3;
1559+ break;
15341560 case TOK_UDIV:
1535− func=TOK___udivsi3;
1536− c=3;
1537− break;
1561+ func = TOK___udivsi3;
1562+ c = 3;
1563+ break;
15381564 case '%':
15391565 #ifdef TCC_ARM_EABI
1540− func=TOK___aeabi_idivmod;
1541− retreg=REG_LRET;
1566+ func = TOK___aeabi_idivmod;
1567+ retreg = REG_LRET;
15421568 #else
1543− func=TOK___modsi3;
1569+ func = TOK___modsi3;
15441570 #endif
1545− c=3;
1546− break;
1571+ c = 3;
1572+ break;
15471573 case TOK_UMOD:
15481574 #ifdef TCC_ARM_EABI
1549− func=TOK___aeabi_uidivmod;
1550− retreg=REG_LRET;
1575+ func = TOK___aeabi_uidivmod;
1576+ retreg = REG_LRET;
15511577 #else
1552− func=TOK___umodsi3;
1578+ func = TOK___umodsi3;
15531579 #endif
1554− c=3;
1555− break;
1580+ c = 3;
1581+ break;
15561582 case TOK_UMULL:
1557− gv2(RC_INT, RC_INT);
1558− r=intr(vtop[-1].r2=get_reg(RC_INT));
1559− c=vtop[-1].r;
1560− vtop[-1].r=get_reg_ex(RC_INT,regmask(c));
1561− vtop--;
1562− o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));
1563− return;
1583+ gv2(RC_INT, RC_INT);
1584+ r = intr(vtop[-1].r2 = get_reg(RC_INT));
1585+ c = vtop[-1].r;
1586+ vtop[-1].r = get_reg_ex(RC_INT, regmask(c));
1587+ vtop--;
1588+ o(0xE0800090 | (r << 16) | (intr(vtop->r) << 12) | (intr(c) << 8) |
1589+ intr(vtop[1].r));
1590+ return;
15641591 default:
1565− opc = 0x15;
1566− c=1;
1567− break;
1568− }
1569− switch(c) {
1592+ opc = 0x15;
1593+ c = 1;
1594+ break;
1595+ }
1596+ switch (c) {
15701597 case 1:
1571− if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1572− if(opc == 4 || opc == 5 || opc == 0xc) {
1573− vswap();
1574− opc|=2; // sub -> rsb
1575− }
1576− }
1577− if ((vtop->r & VT_VALMASK) == VT_CMP ||
1578− (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1579− gv(RC_INT);
1580− vswap();
1581− c=intr(gv(RC_INT));
1582− vswap();
1583− opc=0xE0000000|(opc<<20)|(c<<16);
1584− if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1585− uint32_t x;
1586− x=stuff_const(opc|0x2000000,vtop->c.i);
1587− if(x) {
1588− r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
1589− o(x|(r<<12));
1590− goto done;
1591− }
1592− }
1593− fr=intr(gv(RC_INT));
1594− r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
1595− o(opc|(r<<12)|fr);
1596−done:
1597− vtop--;
1598− if (op >= TOK_ULT && op <= TOK_GT) {
1599− vtop->r = VT_CMP;
1600− vtop->c.i = op;
1601− }
1602− break;
1598+ if ((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1599+ if (opc == 4 || opc == 5 || opc == 0xc) {
1600+ vswap();
1601+ opc |= 2; // sub -> rsb
1602+ }
1603+ }
1604+ if ((vtop->r & VT_VALMASK) == VT_CMP ||
1605+ (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1606+ gv(RC_INT);
1607+ vswap();
1608+ c = intr(gv(RC_INT));
1609+ vswap();
1610+ opc = 0xE0000000 | (opc << 20) | (c << 16);
1611+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1612+ uint32_t x;
1613+ x = stuff_const(opc | 0x2000000, vtop->c.i);
1614+ if (x) {
1615+ r = intr(vtop[-1].r = get_reg_ex(RC_INT, regmask(vtop[-1].r)));
1616+ o(x | (r << 12));
1617+ goto done;
1618+ }
1619+ }
1620+ fr = intr(gv(RC_INT));
1621+ r = intr(vtop[-1].r =
1622+ get_reg_ex(RC_INT, two2mask(vtop->r, vtop[-1].r)));
1623+ o(opc | (r << 12) | fr);
1624+ done:
1625+ vtop--;
1626+ if (op >= TOK_ULT && op <= TOK_GT) {
1627+ vtop->r = VT_CMP;
1628+ vtop->c.i = op;
1629+ }
1630+ break;
16031631 case 2:
1604− opc=0xE1A00000|(opc<<5);
1605− if ((vtop->r & VT_VALMASK) == VT_CMP ||
1606− (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1607− gv(RC_INT);
1608− vswap();
1609− r=intr(gv(RC_INT));
1610− vswap();
1611− opc|=r;
1612− if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1613− fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
1614− c = vtop->c.i & 0x1f;
1615− o(opc|(c<<7)|(fr<<12));
1616− } else {
1617− fr=intr(gv(RC_INT));
1618− c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
1619− o(opc|(c<<12)|(fr<<8)|0x10);
1620− }
1621− vtop--;
1622− break;
1632+ opc = 0xE1A00000 | (opc << 5);
1633+ if ((vtop->r & VT_VALMASK) == VT_CMP ||
1634+ (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1635+ gv(RC_INT);
1636+ vswap();
1637+ r = intr(gv(RC_INT));
1638+ vswap();
1639+ opc |= r;
1640+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1641+ fr = intr(vtop[-1].r = get_reg_ex(RC_INT, regmask(vtop[-1].r)));
1642+ c = vtop->c.i & 0x1f;
1643+ o(opc | (c << 7) | (fr << 12));
1644+ } else {
1645+ fr = intr(gv(RC_INT));
1646+ c = intr(vtop[-1].r =
1647+ get_reg_ex(RC_INT, two2mask(vtop->r, vtop[-1].r)));
1648+ o(opc | (c << 12) | (fr << 8) | 0x10);
1649+ }
1650+ vtop--;
1651+ break;
16231652 case 3:
1624− vpush_global_sym(&func_old_type, func);
1625− vrott(3);
1626− gfunc_call(2);
1627− vpushi(0);
1628− vtop->r = retreg;
1629− break;
1653+ vpush_global_sym(&func_old_type, func);
1654+ vrott(3);
1655+ gfunc_call(2);
1656+ vpushi(0);
1657+ vtop->r = retreg;
1658+ break;
16301659 default:
1631− tcc_error("gen_opi %i unimplemented!",op);
1632− }
1660+ tcc_error("gen_opi %i unimplemented!", op);
1661+ }
16331662 }
16341663
16351664 #ifdef TCC_ARM_VFP
16361665 static int is_zero(int i)
16371666 {
1638− if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1639− return 0;
1640− if (vtop[i].type.t == VT_FLOAT)
1641− return (vtop[i].c.f == 0.f);
1642− else if (vtop[i].type.t == VT_DOUBLE)
1643− return (vtop[i].c.d == 0.0);
1644− return (vtop[i].c.ld == 0.l);
1667+ if ((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1668+ return 0;
1669+ if (vtop[i].type.t == VT_FLOAT)
1670+ return (vtop[i].c.f == 0.f);
1671+ else if (vtop[i].type.t == VT_DOUBLE)
1672+ return (vtop[i].c.d == 0.0);
1673+ return (vtop[i].c.ld == 0.l);
16451674 }
16461675
16471676 /* generate a floating point operation 'v = t1 op t2' instruction. The
16481677 * two operands are guaranted to have the same floating point type */
16491678 void gen_opf(int op)
16501679 {
1651− uint32_t x;
1652− int fneg=0,r;
1653− x=0xEE000A00|T2CPR(vtop->type.t);
1654− switch(op) {
1680+ uint32_t x;
1681+ int fneg = 0, r;
1682+ x = 0xEE000A00 | T2CPR(vtop->type.t);
1683+ switch (op) {
16551684 case '+':
1656− if(is_zero(-1))
1657− vswap();
1658− if(is_zero(0)) {
1659− vtop--;
1660− return;
1661− }
1662− x|=0x300000;
1663− break;
1685+ if (is_zero(-1))
1686+ vswap();
1687+ if (is_zero(0)) {
1688+ vtop--;
1689+ return;
1690+ }
1691+ x |= 0x300000;
1692+ break;
16641693 case '-':
1665− x|=0x300040;
1666− if(is_zero(0)) {
1667− vtop--;
1668− return;
1669− }
1670− if(is_zero(-1)) {
1671− x|=0x810000; /* fsubX -> fnegX */
1672− vswap();
1673− vtop--;
1674− fneg=1;
1675− }
1676− break;
1694+ x |= 0x300040;
1695+ if (is_zero(0)) {
1696+ vtop--;
1697+ return;
1698+ }
1699+ if (is_zero(-1)) {
1700+ x |= 0x810000; /* fsubX -> fnegX */
1701+ vswap();
1702+ vtop--;
1703+ fneg = 1;
1704+ }
1705+ break;
16771706 case '*':
1678− x|=0x200000;
1679− break;
1707+ x |= 0x200000;
1708+ break;
16801709 case '/':
1681− x|=0x800000;
1682− break;
1710+ x |= 0x800000;
1711+ break;
16831712 default:
1684− if(op < TOK_ULT || op > TOK_GT) {
1685− tcc_error("unknown fp op %x!",op);
1686− return;
1687− }
1688− if(is_zero(-1)) {
1689− vswap();
1713+ if (op < TOK_ULT || op > TOK_GT) {
1714+ tcc_error("unknown fp op %x!", op);
1715+ return;
1716+ }
1717+ if (is_zero(-1)) {
1718+ vswap();
16901719 switch(op) {
1691− case TOK_LT: op=TOK_GT; break;
1692− case TOK_GE: op=TOK_ULE; break;
1693− case TOK_LE: op=TOK_GE; break;
1694− case TOK_GT: op=TOK_ULT; break;
1720+ case TOK_LT: op = TOK_GT; break;
1721+ case TOK_GE: op = TOK_ULE; break;
1722+ case TOK_LE: op = TOK_GE; break;
1723+ case TOK_GT: op = TOK_ULT; break;
16951724 }
1696− }
1697− x|=0xB40040; /* fcmpX */
1698− if(op!=TOK_EQ && op!=TOK_NE)
1699− x|=0x80; /* fcmpX -> fcmpeX */
1700− if(is_zero(0)) {
1701− vtop--;
1702− o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
1703− } else {
1704− x|=vfpr(gv(RC_FLOAT));
1705− vswap();
1706− o(x|(vfpr(gv(RC_FLOAT))<<12));
1707− vtop--;
1708− }
1709− o(0xEEF1FA10); /* fmstat */
1725+ }
1726+ x |= 0xB40040; /* fcmpX */
1727+ if (op != TOK_EQ && op != TOK_NE)
1728+ x |= 0x80; /* fcmpX -> fcmpeX */
1729+ if (is_zero(0)) {
1730+ vtop--;
1731+ o(x | 0x10000 |
1732+ (vfpr(gv(RC_FLOAT)) << 12)); /* fcmp(e)X -> fcmp(e)zX */
1733+ } else {
1734+ x |= vfpr(gv(RC_FLOAT));
1735+ vswap();
1736+ o(x | (vfpr(gv(RC_FLOAT)) << 12));
1737+ vtop--;
1738+ }
1739+ o(0xEEF1FA10); /* fmstat */
17101740
17111741 switch(op) {
1712− case TOK_LE: op=TOK_ULE; break;
1713− case TOK_LT: op=TOK_ULT; break;
1714− case TOK_UGE: op=TOK_GE; break;
1715− case TOK_UGT: op=TOK_GT; break;
1742+ case TOK_LE: op = TOK_ULE; break;
1743+ case TOK_LT: op = TOK_ULT; break;
1744+ case TOK_UGE: op = TOK_GE; break;
1745+ case TOK_UGT: op = TOK_GT; break;
17161746 }
17171747
1718− vtop->r = VT_CMP;
1719− vtop->c.i = op;
1720− return;
1721− }
1722− r=gv(RC_FLOAT);
1723− x|=vfpr(r);
1724− r=regmask(r);
1725− if(!fneg) {
1726− int r2;
1727− vswap();
1728− r2=gv(RC_FLOAT);
1729− x|=vfpr(r2)<<16;
1730− r|=regmask(r2);
1731− }
1732− vtop->r=get_reg_ex(RC_FLOAT,r);
1733− if(!fneg)
1734− vtop--;
1735− o(x|(vfpr(vtop->r)<<12));
1748+ vtop->r = VT_CMP;
1749+ vtop->c.i = op;
1750+ return;
1751+ }
1752+ r = gv(RC_FLOAT);
1753+ x |= vfpr(r);
1754+ r = regmask(r);
1755+ if (!fneg) {
1756+ int r2;
1757+ vswap();
1758+ r2 = gv(RC_FLOAT);
1759+ x |= vfpr(r2) << 16;
1760+ r |= regmask(r2);
1761+ }
1762+ vtop->r = get_reg_ex(RC_FLOAT, r);
1763+ if (!fneg)
1764+ vtop--;
1765+ o(x | (vfpr(vtop->r) << 12));
17361766 }
17371767
17381768 #else
17391769 static uint32_t is_fconst()
17401770 {
1741− long double f;
1742− uint32_t r;
1743− if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1744− return 0;
1745− if (vtop->type.t == VT_FLOAT)
1746− f = vtop->c.f;
1747− else if (vtop->type.t == VT_DOUBLE)
1748− f = vtop->c.d;
1749− else
1750− f = vtop->c.ld;
1751− if(!ieee_finite(f))
1771+ long double f;
1772+ uint32_t r;
1773+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1774+ return 0;
1775+ if (vtop->type.t == VT_FLOAT)
1776+ f = vtop->c.f;
1777+ else if (vtop->type.t == VT_DOUBLE)
1778+ f = vtop->c.d;
1779+ else
1780+ f = vtop->c.ld;
1781+ if (!ieee_finite(f))
1782+ return 0;
1783+ r = 0x8;
1784+ if (f < 0.0) {
1785+ r = 0x18;
1786+ f = -f;
1787+ }
1788+ if (f == 0.0)
1789+ return r;
1790+ if (f == 1.0)
1791+ return r | 1;
1792+ if (f == 2.0)
1793+ return r | 2;
1794+ if (f == 3.0)
1795+ return r | 3;
1796+ if (f == 4.0)
1797+ return r | 4;
1798+ if (f == 5.0)
1799+ return r | 5;
1800+ if (f == 0.5)
1801+ return r | 6;
1802+ if (f == 10.0)
1803+ return r | 7;
17521804 return 0;
1753− r=0x8;
1754− if(f<0.0) {
1755− r=0x18;
1756− f=-f;
1757− }
1758− if(f==0.0)
1759− return r;
1760− if(f==1.0)
1761− return r|1;
1762− if(f==2.0)
1763− return r|2;
1764− if(f==3.0)
1765− return r|3;
1766− if(f==4.0)
1767− return r|4;
1768− if(f==5.0)
1769− return r|5;
1770− if(f==0.5)
1771− return r|6;
1772− if(f==10.0)
1773− return r|7;
1774− return 0;
17751805 }
17761806
17771807 /* generate a floating point operation 'v = t1 op t2' instruction. The
17781808 two operands are guaranted to have the same floating point type */
17791809 void gen_opf(int op)
17801810 {
1781− uint32_t x, r, r2, c1, c2;
1782− //fputs("gen_opf\n",stderr);
1783− vswap();
1784− c1 = is_fconst();
1785− vswap();
1786− c2 = is_fconst();
1787− x=0xEE000100;
1811+ uint32_t x, r, r2, c1, c2;
1812+ // fputs("gen_opf\n",stderr);
1813+ vswap();
1814+ c1 = is_fconst();
1815+ vswap();
1816+ c2 = is_fconst();
1817+ x = 0xEE000100;
17881818 #if LDOUBLE_SIZE == 8
1789− if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
1790− x|=0x80;
1819+ if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
1820+ x |= 0x80;
17911821 #else
1792− if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1793− x|=0x80;
1794− else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
1795− x|=0x80000;
1822+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1823+ x |= 0x80;
1824+ else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
1825+ x |= 0x80000;
17961826 #endif
1797− switch(op)
1798− {
1827+ switch (op) {
17991828 case '+':
1800− if(!c2) {
1801− vswap();
1802− c2=c1;
1803− }
1804− vswap();
1805− r=fpr(gv(RC_FLOAT));
1806− vswap();
1807− if(c2) {
1808− if(c2>0xf)
1809− x|=0x200000; // suf
1810− r2=c2&0xf;
1811− } else {
1812− r2=fpr(gv(RC_FLOAT));
1813− }
1814− break;
1829+ if (!c2) {
1830+ vswap();
1831+ c2 = c1;
1832+ }
1833+ vswap();
1834+ r = fpr(gv(RC_FLOAT));
1835+ vswap();
1836+ if (c2) {
1837+ if (c2 > 0xf)
1838+ x |= 0x200000; // suf
1839+ r2 = c2 & 0xf;
1840+ } else {
1841+ r2 = fpr(gv(RC_FLOAT));
1842+ }
1843+ break;
18151844 case '-':
1816− if(c2) {
1817− if(c2<=0xf)
1818− x|=0x200000; // suf
1819− r2=c2&0xf;
1820− vswap();
1821− r=fpr(gv(RC_FLOAT));
1822− vswap();
1823− } else if(c1 && c1<=0xf) {
1824− x|=0x300000; // rsf
1825− r2=c1;
1826− r=fpr(gv(RC_FLOAT));
1827− vswap();
1828− } else {
1829− x|=0x200000; // suf
1830− vswap();
1831− r=fpr(gv(RC_FLOAT));
1832− vswap();
1833− r2=fpr(gv(RC_FLOAT));
1834− }
1835− break;
1845+ if (c2) {
1846+ if (c2 <= 0xf)
1847+ x |= 0x200000; // suf
1848+ r2 = c2 & 0xf;
1849+ vswap();
1850+ r = fpr(gv(RC_FLOAT));
1851+ vswap();
1852+ } else if (c1 && c1 <= 0xf) {
1853+ x |= 0x300000; // rsf
1854+ r2 = c1;
1855+ r = fpr(gv(RC_FLOAT));
1856+ vswap();
1857+ } else {
1858+ x |= 0x200000; // suf
1859+ vswap();
1860+ r = fpr(gv(RC_FLOAT));
1861+ vswap();
1862+ r2 = fpr(gv(RC_FLOAT));
1863+ }
1864+ break;
18361865 case '*':
1837− if(!c2 || c2>0xf) {
1838− vswap();
1839− c2=c1;
1840− }
1841− vswap();
1842− r=fpr(gv(RC_FLOAT));
1843− vswap();
1844− if(c2 && c2<=0xf)
1845− r2=c2;
1846− else
1847− r2=fpr(gv(RC_FLOAT));
1848− x|=0x100000; // muf
1849− break;
1866+ if (!c2 || c2 > 0xf) {
1867+ vswap();
1868+ c2 = c1;
1869+ }
1870+ vswap();
1871+ r = fpr(gv(RC_FLOAT));
1872+ vswap();
1873+ if (c2 && c2 <= 0xf)
1874+ r2 = c2;
1875+ else
1876+ r2 = fpr(gv(RC_FLOAT));
1877+ x |= 0x100000; // muf
1878+ break;
18501879 case '/':
1851− if(c2 && c2<=0xf) {
1852− x|=0x400000; // dvf
1853− r2=c2;
1854− vswap();
1855− r=fpr(gv(RC_FLOAT));
1856− vswap();
1857− } else if(c1 && c1<=0xf) {
1858− x|=0x500000; // rdf
1859− r2=c1;
1860− r=fpr(gv(RC_FLOAT));
1861− vswap();
1862− } else {
1863− x|=0x400000; // dvf
1864− vswap();
1865− r=fpr(gv(RC_FLOAT));
1866− vswap();
1867− r2=fpr(gv(RC_FLOAT));
1868− }
1869− break;
1880+ if (c2 && c2 <= 0xf) {
1881+ x |= 0x400000; // dvf
1882+ r2 = c2;
1883+ vswap();
1884+ r = fpr(gv(RC_FLOAT));
1885+ vswap();
1886+ } else if (c1 && c1 <= 0xf) {
1887+ x |= 0x500000; // rdf
1888+ r2 = c1;
1889+ r = fpr(gv(RC_FLOAT));
1890+ vswap();
1891+ } else {
1892+ x |= 0x400000; // dvf
1893+ vswap();
1894+ r = fpr(gv(RC_FLOAT));
1895+ vswap();
1896+ r2 = fpr(gv(RC_FLOAT));
1897+ }
1898+ break;
18701899 default:
1871− if(op >= TOK_ULT && op <= TOK_GT) {
1872− x|=0xd0f110; // cmfe
1873−/* bug (intention?) in Linux FPU emulator
1874− doesn't set carry if equal */
1875− switch(op) {
1876− case TOK_ULT:
1877− case TOK_UGE:
1878− case TOK_ULE:
1879− case TOK_UGT:
1880− tcc_error("unsigned comparison on floats?");
1881− break;
1882− case TOK_LT:
1883− op=TOK_Nset;
1884− break;
1885− case TOK_LE:
1886− op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */
1887− break;
1888− case TOK_EQ:
1889− case TOK_NE:
1890− x&=~0x400000; // cmfe -> cmf
1891− break;
1892− }
1893− if(c1 && !c2) {
1894− c2=c1;
1895− vswap();
1896− switch(op) {
1897− case TOK_Nset:
1898− op=TOK_GT;
1899− break;
1900− case TOK_GE:
1901− op=TOK_ULE;
1902− break;
1903− case TOK_ULE:
1904− op=TOK_GE;
1905− break;
1906− case TOK_GT:
1907− op=TOK_Nset;
1908− break;
1909− }
1910− }
1911− vswap();
1912− r=fpr(gv(RC_FLOAT));
1913− vswap();
1914− if(c2) {
1915− if(c2>0xf)
1916− x|=0x200000;
1917− r2=c2&0xf;
1918− } else {
1919− r2=fpr(gv(RC_FLOAT));
1920− }
1921− vtop[-1].r = VT_CMP;
1922− vtop[-1].c.i = op;
1923− } else {
1924− tcc_error("unknown fp op %x!",op);
1925− return;
1926− }
1927− }
1928− if(vtop[-1].r == VT_CMP)
1929− c1=15;
1930− else {
1931− c1=vtop->r;
1932− if(r2&0x8)
1933− c1=vtop[-1].r;
1934− vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
1935− c1=fpr(vtop[-1].r);
1936− }
1937− vtop--;
1938− o(x|(r<<16)|(c1<<12)|r2);
1900+ if (op >= TOK_ULT && op <= TOK_GT) {
1901+ x |= 0xd0f110; // cmfe
1902+ /* bug (intention?) in Linux FPU emulator
1903+ doesn't set carry if equal */
1904+ switch (op) {
1905+ case TOK_ULT:
1906+ case TOK_UGE:
1907+ case TOK_ULE:
1908+ case TOK_UGT:
1909+ tcc_error("unsigned comparison on floats?");
1910+ break;
1911+ case TOK_LT:
1912+ op = TOK_Nset;
1913+ break;
1914+ case TOK_LE:
1915+ op = TOK_ULE; /* correct in unordered case only if AC bit in
1916+ FPSR set */
1917+ break;
1918+ case TOK_EQ:
1919+ case TOK_NE:
1920+ x &= ~0x400000; // cmfe -> cmf
1921+ break;
1922+ }
1923+ if (c1 && !c2) {
1924+ c2 = c1;
1925+ vswap();
1926+ switch (op) {
1927+ case TOK_Nset:
1928+ op = TOK_GT;
1929+ break;
1930+ case TOK_GE:
1931+ op = TOK_ULE;
1932+ break;
1933+ case TOK_ULE:
1934+ op = TOK_GE;
1935+ break;
1936+ case TOK_GT:
1937+ op = TOK_Nset;
1938+ break;
1939+ }
1940+ }
1941+ vswap();
1942+ r = fpr(gv(RC_FLOAT));
1943+ vswap();
1944+ if (c2) {
1945+ if (c2 > 0xf)
1946+ x |= 0x200000;
1947+ r2 = c2 & 0xf;
1948+ } else {
1949+ r2 = fpr(gv(RC_FLOAT));
1950+ }
1951+ vtop[-1].r = VT_CMP;
1952+ vtop[-1].c.i = op;
1953+ } else {
1954+ tcc_error("unknown fp op %x!", op);
1955+ return;
1956+ }
1957+ }
1958+ if (vtop[-1].r == VT_CMP)
1959+ c1 = 15;
1960+ else {
1961+ c1 = vtop->r;
1962+ if (r2 & 0x8)
1963+ c1 = vtop[-1].r;
1964+ vtop[-1].r = get_reg_ex(RC_FLOAT, two2mask(vtop[-1].r, c1));
1965+ c1 = fpr(vtop[-1].r);
1966+ }
1967+ vtop--;
1968+ o(x | (r << 16) | (c1 << 12) | r2);
19391969 }
19401970 #endif
19411971
@@ -1943,177 +1973,186 @@ void gen_opf(int op) · 1 unmodified line
19431973 and 'long long' cases. */
19441974 ST_FUNC void gen_cvt_itof1(int t)
19451975 {
1946− uint32_t r, r2;
1947− int bt;
1948− bt=vtop->type.t & VT_BTYPE;
1949− if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
1976+ uint32_t r, r2;
1977+ int bt;
1978+ bt = vtop->type.t & VT_BTYPE;
1979+ if (bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
19501980 #ifndef TCC_ARM_VFP
1951− uint32_t dsize = 0;
1981+ uint32_t dsize = 0;
19521982 #endif
1953− r=intr(gv(RC_INT));
1983+ r = intr(gv(RC_INT));
19541984 #ifdef TCC_ARM_VFP
1955− r2=vfpr(vtop->r=get_reg(RC_FLOAT));
1956− o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
1957− r2|=r2<<12;
1958− if(!(vtop->type.t & VT_UNSIGNED))
1959− r2|=0x80; /* fuitoX -> fsituX */
1960− o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
1985+ r2 = vfpr(vtop->r = get_reg(RC_FLOAT));
1986+ o(0xEE000A10 | (r << 12) | (r2 << 16)); /* fmsr */
1987+ r2 |= r2 << 12;
1988+ if (!(vtop->type.t & VT_UNSIGNED))
1989+ r2 |= 0x80; /* fuitoX -> fsituX */
1990+ o(0xEEB80A40 | r2 | T2CPR(t)); /* fYitoX*/
19611991 #else
1962− r2=fpr(vtop->r=get_reg(RC_FLOAT));
1963− if((t & VT_BTYPE) != VT_FLOAT)
1964− dsize=0x80; /* flts -> fltd */
1965− o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
1966− if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
1967− uint32_t off = 0;
1968− o(0xE3500000|(r<<12)); /* cmp */
1969− r=fpr(get_reg(RC_FLOAT));
1970− if(last_itod_magic) {
1971− off=ind+8-last_itod_magic;
1972− off/=4;
1973− if(off>255)
1974− off=0;
1975− }
1976− o(0xBD1F0100|(r<<12)|off); /* ldflts */
1977− if(!off) {
1978− o(0xEA000000); /* b */
1979− last_itod_magic=ind;
1980− o(0x4F800000); /* 4294967296.0f */
1981− }
1982− o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
1983− }
1992+ r2 = fpr(vtop->r = get_reg(RC_FLOAT));
1993+ if ((t & VT_BTYPE) != VT_FLOAT)
1994+ dsize = 0x80; /* flts -> fltd */
1995+ o(0xEE000110 | dsize | (r2 << 16) | (r << 12)); /* flts */
1996+ if ((vtop->type.t & (VT_UNSIGNED | VT_BTYPE)) ==
1997+ (VT_UNSIGNED | VT_INT)) {
1998+ uint32_t off = 0;
1999+ o(0xE3500000 | (r << 12)); /* cmp */
2000+ r = fpr(get_reg(RC_FLOAT));
2001+ if (last_itod_magic) {
2002+ off = ind + 8 - last_itod_magic;
2003+ off /= 4;
2004+ if (off > 255)
2005+ off = 0;
2006+ }
2007+ o(0xBD1F0100 | (r << 12) | off); /* ldflts */
2008+ if (!off) {
2009+ o(0xEA000000); /* b */
2010+ last_itod_magic = ind;
2011+ o(0x4F800000); /* 4294967296.0f */
2012+ }
2013+ o(0xBE000100 | dsize | (r2 << 16) | (r2 << 12) | r); /* adflt */
2014+ }
19842015 #endif
1985− return;
1986− } else if(bt == VT_LLONG) {
1987− int func;
1988− CType *func_type = 0;
1989− if((t & VT_BTYPE) == VT_FLOAT) {
1990− func_type = &func_float_type;
1991− if(vtop->type.t & VT_UNSIGNED)
1992− func=TOK___floatundisf;
1993− else
1994− func=TOK___floatdisf;
2016+ return;
2017+ } else if (bt == VT_LLONG) {
2018+ int func;
2019+ CType* func_type = 0;
2020+ if ((t & VT_BTYPE) == VT_FLOAT) {
2021+ func_type = &func_float_type;
2022+ if (vtop->type.t & VT_UNSIGNED)
2023+ func = TOK___floatundisf;
2024+ else
2025+ func = TOK___floatdisf;
19952026 #if LDOUBLE_SIZE != 8
1996− } else if((t & VT_BTYPE) == VT_LDOUBLE) {
1997− func_type = &func_ldouble_type;
1998− if(vtop->type.t & VT_UNSIGNED)
1999− func=TOK___floatundixf;
2000− else
2001− func=TOK___floatdixf;
2002− } else if((t & VT_BTYPE) == VT_DOUBLE) {
2027+ } else if ((t & VT_BTYPE) == VT_LDOUBLE) {
2028+ func_type = &func_ldouble_type;
2029+ if (vtop->type.t & VT_UNSIGNED)
2030+ func = TOK___floatundixf;
2031+ else
2032+ func = TOK___floatdixf;
2033+ } else if ((t & VT_BTYPE) == VT_DOUBLE) {
20032034 #else
2004− } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
2035+ } else if ((t & VT_BTYPE) == VT_DOUBLE ||
2036+ (t & VT_BTYPE) == VT_LDOUBLE) {
20052037 #endif
2006− func_type = &func_double_type;
2007− if(vtop->type.t & VT_UNSIGNED)
2008− func=TOK___floatundidf;
2009− else
2010− func=TOK___floatdidf;
2011− }
2012− if(func_type) {
2013− vpush_global_sym(func_type, func);
2014− vswap();
2015− gfunc_call(1);
2016− vpushi(0);
2017− vtop->r=TREG_F0;
2018− return;
2038+ func_type = &func_double_type;
2039+ if (vtop->type.t & VT_UNSIGNED)
2040+ func = TOK___floatundidf;
2041+ else
2042+ func = TOK___floatdidf;
2043+ }
2044+ if (func_type) {
2045+ vpush_global_sym(func_type, func);
2046+ vswap();
2047+ gfunc_call(1);
2048+ vpushi(0);
2049+ vtop->r = TREG_F0;
2050+ return;
2051+ }
20192052 }
2020− }
2021− tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);
2053+ tcc_error("unimplemented gen_cvt_itof %x!", vtop->type.t);
20222054 }
20232055
20242056 /* convert fp to int 't' type */
20252057 void gen_cvt_ftoi(int t)
20262058 {
2027− uint32_t r, r2;
2028− int u, func = 0;
2029− u=t&VT_UNSIGNED;
2030− t&=VT_BTYPE;
2031− r2=vtop->type.t & VT_BTYPE;
2032− if(t==VT_INT) {
2059+ uint32_t r, r2;
2060+ int u, func = 0;
2061+ u = t & VT_UNSIGNED;
2062+ t &= VT_BTYPE;
2063+ r2 = vtop->type.t & VT_BTYPE;
2064+ if (t == VT_INT) {
20332065 #ifdef TCC_ARM_VFP
2034− r=vfpr(gv(RC_FLOAT));
2035− u=u?0:0x10000;
2036− o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
2037− r2=intr(vtop->r=get_reg(RC_INT));
2038− o(0xEE100A10|(r<<16)|(r2<<12));
2039− return;
2066+ r = vfpr(gv(RC_FLOAT));
2067+ u = u ? 0 : 0x10000;
2068+ o(0xEEBC0AC0 | (r << 12) | r | T2CPR(r2) | u); /* ftoXizY */
2069+ r2 = intr(vtop->r = get_reg(RC_INT));
2070+ o(0xEE100A10 | (r << 16) | (r2 << 12));
2071+ return;
20402072 #else
2041− if(u) {
2042− if(r2 == VT_FLOAT)
2043− func=TOK___fixunssfsi;
2073+ if (u) {
2074+ if (r2 == VT_FLOAT)
2075+ func = TOK___fixunssfsi;
20442076 #if LDOUBLE_SIZE != 8
2045− else if(r2 == VT_LDOUBLE)
2046− func=TOK___fixunsxfsi;
2047− else if(r2 == VT_DOUBLE)
2077+ else if (r2 == VT_LDOUBLE)
2078+ func = TOK___fixunsxfsi;
2079+ else if (r2 == VT_DOUBLE)
20482080 #else
2049− else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
2081+ else if (r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
20502082 #endif
2051− func=TOK___fixunsdfsi;
2052− } else {
2053− r=fpr(gv(RC_FLOAT));
2054− r2=intr(vtop->r=get_reg(RC_INT));
2055− o(0xEE100170|(r2<<12)|r);
2056− return;
2057− }
2083+ func = TOK___fixunsdfsi;
2084+ } else {
2085+ r = fpr(gv(RC_FLOAT));
2086+ r2 = intr(vtop->r = get_reg(RC_INT));
2087+ o(0xEE100170 | (r2 << 12) | r);
2088+ return;
2089+ }
20582090 #endif
2059− } else if(t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1
2060− if(r2 == VT_FLOAT)
2061− func=TOK___fixsfdi;
2091+ } else if (t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1
2092+ if (r2 == VT_FLOAT)
2093+ func = TOK___fixsfdi;
20622094 #if LDOUBLE_SIZE != 8
2063− else if(r2 == VT_LDOUBLE)
2064− func=TOK___fixxfdi;
2065− else if(r2 == VT_DOUBLE)
2095+ else if (r2 == VT_LDOUBLE)
2096+ func = TOK___fixxfdi;
2097+ else if (r2 == VT_DOUBLE)
20662098 #else
2067− else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
2099+ else if (r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
20682100 #endif
2069− func=TOK___fixdfdi;
2070− }
2071− if(func) {
2072− vpush_global_sym(&func_old_type, func);
2073− vswap();
2074− gfunc_call(1);
2075− vpushi(0);
2076− if(t == VT_LLONG)
2077− vtop->r2 = REG_LRET;
2078− vtop->r = REG_IRET;
2079− return;
2080− }
2081− tcc_error("unimplemented gen_cvt_ftoi!");
2101+ func = TOK___fixdfdi;
2102+ }
2103+ if (func) {
2104+ vpush_global_sym(&func_old_type, func);
2105+ vswap();
2106+ gfunc_call(1);
2107+ vpushi(0);
2108+ if (t == VT_LLONG)
2109+ vtop->r2 = REG_LRET;
2110+ vtop->r = REG_IRET;
2111+ return;
2112+ }
2113+ tcc_error("unimplemented gen_cvt_ftoi!");
20822114 }
20832115
20842116 /* convert from one floating point type to another */
20852117 void gen_cvt_ftof(int t)
20862118 {
20872119 #ifdef TCC_ARM_VFP
2088− if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
2089− uint32_t r = vfpr(gv(RC_FLOAT));
2090− o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
2091− }
2120+ if (((vtop->type.t & VT_BTYPE) == VT_FLOAT) !=
2121+ ((t & VT_BTYPE) == VT_FLOAT)) {
2122+ uint32_t r = vfpr(gv(RC_FLOAT));
2123+ o(0xEEB70AC0 | (r << 12) | r | T2CPR(vtop->type.t));
2124+ }
20922125 #else
2093− /* all we have to do on i386 and FPA ARM is to put the float in a register */
2094− gv(RC_FLOAT);
2126+ /* all we have to do on i386 and FPA ARM is to put the float in a register
2127+ */
2128+ gv(RC_FLOAT);
20952129 #endif
20962130 }
20972131
20982132 /* computed goto support */
20992133 void ggoto(void)
21002134 {
2101− gcall_or_jmp(1);
2102− vtop--;
2135+ gcall_or_jmp(1);
2136+ vtop--;
21032137 }
21042138
2105−/* Save the stack pointer onto the stack and return the location of its address */
2106−ST_FUNC void gen_vla_sp_save(int addr) {
2139+/* Save the stack pointer onto the stack and return the location of its address
2140+ */
2141+ST_FUNC void gen_vla_sp_save(int addr)
2142+{
21072143 tcc_error("variable length arrays unsupported for this target");
21082144 }
21092145
21102146 /* Restore the SP from a location on the stack */
2111−ST_FUNC void gen_vla_sp_restore(int addr) {
2147+ST_FUNC void gen_vla_sp_restore(int addr)
2148+{
21122149 tcc_error("variable length arrays unsupported for this target");
21132150 }
21142151
2115−/* Subtract from the stack pointer, and push the resulting value onto the stack */
2116−ST_FUNC void gen_vla_alloc(CType *type, int align) {
2152+/* Subtract from the stack pointer, and push the resulting value onto the stack
2153+ */
2154+ST_FUNC void gen_vla_alloc(CType* type, int align)
2155+{
21172156 tcc_error("variable length arrays unsupported for this target");
21182157 }
21192158
tcccoff.c+638−662
@@ -21,9 +21,9 @@ · 20 unmodified lines
2121
2222 #include "tcc.h"
2323
24−#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
24+#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
2525 #define MAX_STR_TABLE 1000000
26−AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
26+AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
2727
2828 SCNHDR section_header[MAXNSCNS];
2929
@@ -38,14 +38,14 @@ int EndAddress[MAX_FUNCS]; · 8 unmodified lines
3838 int LastLineNo[MAX_FUNCS];
3939 int FuncEntries[MAX_FUNCS];
4040
41−int OutputTheSection(Section * sect);
42−short int GetCoffFlags(const char *s);
41+int OutputTheSection(Section* sect);
42+short int GetCoffFlags(const char* s);
4343 void SortSymbolTable(void);
44−Section *FindSection(TCCState * s1, const char *sname);
44+Section* FindSection(TCCState* s1, const char* sname);
4545
4646 int C67_main_entry_point;
4747
48−int FindCoffSymbolIndex(const char *func_name);
48+int FindCoffSymbolIndex(const char* func_name);
4949 int nb_syms;
5050
5151 typedef struct {
@@ -74,15 +74,15 @@ typedef struct { · 22 unmodified lines
7474 unsigned short dummy4;
7575 } AUXEF;
7676
77−ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
77+ST_FUNC int tcc_output_coff(TCCState* s1, FILE* f)
7878 {
79− Section *tcc_sect;
80− SCNHDR *coff_sec;
79+ Section* tcc_sect;
80+ SCNHDR* coff_sec;
8181 int file_pointer;
82− char *Coff_str_table, *pCoff_str_table;
82+ char* Coff_str_table, *pCoff_str_table;
8383 int CoffTextSectionNo, coff_nb_syms;
84− FILHDR file_hdr; /* FILE HEADER STRUCTURE */
85− Section *stext, *sdata, *sbss;
84+ FILHDR file_hdr; /* FILE HEADER STRUCTURE */
85+ Section* stext, *sdata, *sbss;
8686 int i, NSectionsToOutput = 0;
8787
8888 Coff_str_table = pCoff_str_table = NULL;
@@ -94,21 +94,21 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f) · 5 unmodified lines
9494 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
9595 coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
9696
97− file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
98− file_hdr.f_timdat = 0; /* time & date stamp */
99− file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
100− file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
101− file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
102−
103− o_filehdr.magic = 0x0108; /* see magic.h */
104− o_filehdr.vstamp = 0x0190; /* version stamp */
105− o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
106− o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
107− o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
108− o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
109− o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
110− o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
111−
97+ file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
98+ file_hdr.f_timdat = 0; /* time & date stamp */
99+ file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
100+ file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
101+ file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
102+
103+ o_filehdr.magic = 0x0108; /* see magic.h */
104+ o_filehdr.vstamp = 0x0190; /* version stamp */
105+ o_filehdr.tsize =
106+ stext->data_offset; /* text size in bytes, padded to FW bdry */
107+ o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
108+ o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
109+ o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
110+ o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
111+ o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
112112
113113 // create all the section headers
114114
@@ -117,831 +117,807 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f) · 2 unmodified lines
117117 CoffTextSectionNo = -1;
118118
119119 for (i = 1; i < s1->nb_sections; i++) {
120− coff_sec = &section_header[i];
121− tcc_sect = s1->sections[i];
122−
123− if (OutputTheSection(tcc_sect)) {
124− NSectionsToOutput++;
125−
126− if (CoffTextSectionNo == -1 && tcc_sect == stext)
127− CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
128−
129− strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
130−
131− coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
132− coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
133− coff_sec->s_size = tcc_sect->data_offset; /* section size */
134− coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
135− coff_sec->s_relptr = 0; /* file ptr to relocation */
136− coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
137− coff_sec->s_nreloc = 0; /* number of relocation entries */
138− coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
139− coff_sec->s_reserved = 0; /* reserved byte */
140− coff_sec->s_page = 0; /* memory page id */
141−
142− file_pointer += sizeof(SCNHDR);
143− }
120+ coff_sec = &section_header[i];
121+ tcc_sect = s1->sections[i];
122+
123+ if (OutputTheSection(tcc_sect)) {
124+ NSectionsToOutput++;
125+
126+ if (CoffTextSectionNo == -1 && tcc_sect == stext)
127+ CoffTextSectionNo = NSectionsToOutput; // rem which coff sect
128+ // number the .text sect
129+ // is
130+
131+ strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
132+
133+ coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
134+ coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
135+ coff_sec->s_size = tcc_sect->data_offset; /* section size */
136+ coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
137+ coff_sec->s_relptr = 0; /* file ptr to relocation */
138+ coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
139+ coff_sec->s_nreloc = 0; /* number of relocation entries */
140+ coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
141+ coff_sec->s_reserved = 0; /* reserved byte */
142+ coff_sec->s_page = 0; /* memory page id */
143+
144+ file_pointer += sizeof(SCNHDR);
145+ }
144146 }
145147
146− file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
148+ file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
147149
148150 // now loop through and determine file pointer locations
149151 // for the raw data
150152
151−
152153 for (i = 1; i < s1->nb_sections; i++) {
153− coff_sec = &section_header[i];
154− tcc_sect = s1->sections[i];
155−
156− if (OutputTheSection(tcc_sect)) {
157− // put raw data
158− coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
159− file_pointer += coff_sec->s_size;
160− }
154+ coff_sec = &section_header[i];
155+ tcc_sect = s1->sections[i];
156+
157+ if (OutputTheSection(tcc_sect)) {
158+ // put raw data
159+ coff_sec->s_scnptr =
160+ file_pointer; /* file ptr to raw data for section */
161+ file_pointer += coff_sec->s_size;
162+ }
161163 }
162164
163165 // now loop through and determine file pointer locations
164166 // for the relocation data
165167
166168 for (i = 1; i < s1->nb_sections; i++) {
167− coff_sec = &section_header[i];
168− tcc_sect = s1->sections[i];
169−
170− if (OutputTheSection(tcc_sect)) {
171− // put relocations data
172− if (coff_sec->s_nreloc > 0) {
173− coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
174− file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
175− }
176− }
169+ coff_sec = &section_header[i];
170+ tcc_sect = s1->sections[i];
171+
172+ if (OutputTheSection(tcc_sect)) {
173+ // put relocations data
174+ if (coff_sec->s_nreloc > 0) {
175+ coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
176+ file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
177+ }
178+ }
177179 }
178180
179181 // now loop through and determine file pointer locations
180182 // for the line number data
181183
182184 for (i = 1; i < s1->nb_sections; i++) {
183− coff_sec = &section_header[i];
184− tcc_sect = s1->sections[i];
185−
186− coff_sec->s_nlnno = 0;
187− coff_sec->s_lnnoptr = 0;
188−
189− if (s1->do_debug && tcc_sect == stext) {
190− // count how many line nos data
191−
192− // also find association between source file name and function
193− // so we can sort the symbol table
194−
195−
196− Stab_Sym *sym, *sym_end;
197− char func_name[MAX_FUNC_NAME_LENGTH],
198− last_func_name[MAX_FUNC_NAME_LENGTH];
199− unsigned long func_addr, last_pc, pc;
200− const char *incl_files[INCLUDE_STACK_SIZE];
201− int incl_index, len, last_line_num;
202− const char *str, *p;
203−
204− coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
205−
206−
207− func_name[0] = '\0';
208− func_addr = 0;
209− incl_index = 0;
210− last_func_name[0] = '\0';
211− last_pc = 0xffffffff;
212− last_line_num = 1;
213− sym = (Stab_Sym *) stab_section->data + 1;
214− sym_end =
215− (Stab_Sym *) (stab_section->data +
216− stab_section->data_offset);
217−
218− nFuncs = 0;
219− while (sym < sym_end) {
220− switch (sym->n_type) {
221− /* function start or end */
222− case N_FUN:
223− if (sym->n_strx == 0) {
224− // end of function
225−
226− coff_sec->s_nlnno++;
227− file_pointer += LINESZ;
228−
229− pc = sym->n_value + func_addr;
230− func_name[0] = '\0';
231− func_addr = 0;
232− EndAddress[nFuncs] = pc;
233− FuncEntries[nFuncs] =
234− (file_pointer -
235− LineNoFilePtr[nFuncs]) / LINESZ - 1;
236− LastLineNo[nFuncs++] = last_line_num + 1;
237− } else {
238− // beginning of function
239−
240− LineNoFilePtr[nFuncs] = file_pointer;
241− coff_sec->s_nlnno++;
242− file_pointer += LINESZ;
243−
244− str =
245− (const char *) stabstr_section->data +
246− sym->n_strx;
247−
248− p = strchr(str, ':');
249− if (!p) {
250− pstrcpy(func_name, sizeof(func_name), str);
251− pstrcpy(Func[nFuncs], sizeof(func_name), str);
252− } else {
253− len = p - str;
254− if (len > sizeof(func_name) - 1)
255− len = sizeof(func_name) - 1;
256− memcpy(func_name, str, len);
257− memcpy(Func[nFuncs], str, len);
258− func_name[len] = '\0';
259− }
260−
261− // save the file that it came in so we can sort later
262− pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
263− incl_files[incl_index - 1]);
264−
265− func_addr = sym->n_value;
266− }
267− break;
268−
269− /* line number info */
270− case N_SLINE:
271− pc = sym->n_value + func_addr;
272−
273− last_pc = pc;
274− last_line_num = sym->n_desc;
275−
276− /* XXX: slow! */
277− strcpy(last_func_name, func_name);
278−
279− coff_sec->s_nlnno++;
280− file_pointer += LINESZ;
281− break;
282− /* include files */
283− case N_BINCL:
284− str =
285− (const char *) stabstr_section->data + sym->n_strx;
286− add_incl:
287− if (incl_index < INCLUDE_STACK_SIZE) {
288− incl_files[incl_index++] = str;
289− }
290− break;
291− case N_EINCL:
292− if (incl_index > 1)
293− incl_index--;
294− break;
295− case N_SO:
296− if (sym->n_strx == 0) {
297− incl_index = 0; /* end of translation unit */
298− } else {
299− str =
300− (const char *) stabstr_section->data +
301− sym->n_strx;
302− /* do not add path */
303− len = strlen(str);
304− if (len > 0 && str[len - 1] != '/')
305− goto add_incl;
306− }
307− break;
308− }
309− sym++;
310− }
311− }
312−
185+ coff_sec = &section_header[i];
186+ tcc_sect = s1->sections[i];
187+
188+ coff_sec->s_nlnno = 0;
189+ coff_sec->s_lnnoptr = 0;
190+
191+ if (s1->do_debug && tcc_sect == stext) {
192+ // count how many line nos data
193+
194+ // also find association between source file name and function
195+ // so we can sort the symbol table
196+
197+ Stab_Sym* sym, *sym_end;
198+ char func_name[MAX_FUNC_NAME_LENGTH],
199+ last_func_name[MAX_FUNC_NAME_LENGTH];
200+ unsigned long func_addr, last_pc, pc;
201+ const char* incl_files[INCLUDE_STACK_SIZE];
202+ int incl_index, len, last_line_num;
203+ const char* str, *p;
204+
205+ coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
206+
207+ func_name[0] = '\0';
208+ func_addr = 0;
209+ incl_index = 0;
210+ last_func_name[0] = '\0';
211+ last_pc = 0xffffffff;
212+ last_line_num = 1;
213+ sym = (Stab_Sym*)stab_section->data + 1;
214+ sym_end =
215+ (Stab_Sym*)(stab_section->data + stab_section->data_offset);
216+
217+ nFuncs = 0;
218+ while (sym < sym_end) {
219+ switch (sym->n_type) {
220+ /* function start or end */
221+ case N_FUN:
222+ if (sym->n_strx == 0) {
223+ // end of function
224+
225+ coff_sec->s_nlnno++;
226+ file_pointer += LINESZ;
227+
228+ pc = sym->n_value + func_addr;
229+ func_name[0] = '\0';
230+ func_addr = 0;
231+ EndAddress[nFuncs] = pc;
232+ FuncEntries[nFuncs] =
233+ (file_pointer - LineNoFilePtr[nFuncs]) / LINESZ - 1;
234+ LastLineNo[nFuncs++] = last_line_num + 1;
235+ } else {
236+ // beginning of function
237+
238+ LineNoFilePtr[nFuncs] = file_pointer;
239+ coff_sec->s_nlnno++;
240+ file_pointer += LINESZ;
241+
242+ str = (const char*)stabstr_section->data + sym->n_strx;
243+
244+ p = strchr(str, ':');
245+ if (!p) {
246+ pstrcpy(func_name, sizeof(func_name), str);
247+ pstrcpy(Func[nFuncs], sizeof(func_name), str);
248+ } else {
249+ len = p - str;
250+ if (len > sizeof(func_name) - 1)
251+ len = sizeof(func_name) - 1;
252+ memcpy(func_name, str, len);
253+ memcpy(Func[nFuncs], str, len);
254+ func_name[len] = '\0';
255+ }
256+
257+ // save the file that it came in so we can sort later
258+ pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
259+ incl_files[incl_index - 1]);
260+
261+ func_addr = sym->n_value;
262+ }
263+ break;
264+
265+ /* line number info */
266+ case N_SLINE:
267+ pc = sym->n_value + func_addr;
268+
269+ last_pc = pc;
270+ last_line_num = sym->n_desc;
271+
272+ /* XXX: slow! */
273+ strcpy(last_func_name, func_name);
274+
275+ coff_sec->s_nlnno++;
276+ file_pointer += LINESZ;
277+ break;
278+ /* include files */
279+ case N_BINCL:
280+ str = (const char*)stabstr_section->data + sym->n_strx;
281+ add_incl:
282+ if (incl_index < INCLUDE_STACK_SIZE) {
283+ incl_files[incl_index++] = str;
284+ }
285+ break;
286+ case N_EINCL:
287+ if (incl_index > 1)
288+ incl_index--;
289+ break;
290+ case N_SO:
291+ if (sym->n_strx == 0) {
292+ incl_index = 0; /* end of translation unit */
293+ } else {
294+ str = (const char*)stabstr_section->data + sym->n_strx;
295+ /* do not add path */
296+ len = strlen(str);
297+ if (len > 0 && str[len - 1] != '/')
298+ goto add_incl;
299+ }
300+ break;
301+ }
302+ sym++;
303+ }
304+ }
313305 }
314306
315− file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
307+ file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
316308
317309 if (s1->do_debug)
318− file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
310+ file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
319311 else
320− file_hdr.f_nsyms = 0;
312+ file_hdr.f_nsyms = 0;
321313
322314 file_pointer += file_hdr.f_nsyms * SYMNMLEN;
323315
324316 // OK now we are all set to write the file
325317
326−
327318 fwrite(&file_hdr, FILHSZ, 1, f);
328319 fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
329320
330321 // write section headers
331322 for (i = 1; i < s1->nb_sections; i++) {
332− coff_sec = &section_header[i];
333− tcc_sect = s1->sections[i];
323+ coff_sec = &section_header[i];
324+ tcc_sect = s1->sections[i];
334325
335− if (OutputTheSection(tcc_sect)) {
336− fwrite(coff_sec, sizeof(SCNHDR), 1, f);
337− }
326+ if (OutputTheSection(tcc_sect)) {
327+ fwrite(coff_sec, sizeof(SCNHDR), 1, f);
328+ }
338329 }
339330
340331 // write raw data
341332 for (i = 1; i < s1->nb_sections; i++) {
342− coff_sec = &section_header[i];
343− tcc_sect = s1->sections[i];
333+ coff_sec = &section_header[i];
334+ tcc_sect = s1->sections[i];
344335
345− if (OutputTheSection(tcc_sect)) {
346− fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
347− }
336+ if (OutputTheSection(tcc_sect)) {
337+ fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
338+ }
348339 }
349340
350341 // write relocation data
351342 for (i = 1; i < s1->nb_sections; i++) {
352− coff_sec = &section_header[i];
353− tcc_sect = s1->sections[i];
354−
355− if (OutputTheSection(tcc_sect)) {
356− // put relocations data
357− if (coff_sec->s_nreloc > 0) {
358− fwrite(tcc_sect->reloc,
359− coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
360− }
361− }
343+ coff_sec = &section_header[i];
344+ tcc_sect = s1->sections[i];
345+
346+ if (OutputTheSection(tcc_sect)) {
347+ // put relocations data
348+ if (coff_sec->s_nreloc > 0) {
349+ fwrite(tcc_sect->reloc,
350+ coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
351+ }
352+ }
362353 }
363354
364−
365355 // group the symbols in order of filename, func1, func2, etc
366356 // finally global symbols
367357
368358 if (s1->do_debug)
369− SortSymbolTable();
359+ SortSymbolTable();
370360
371361 // write line no data
372362
373363 for (i = 1; i < s1->nb_sections; i++) {
374− coff_sec = &section_header[i];
375− tcc_sect = s1->sections[i];
376−
377− if (s1->do_debug && tcc_sect == stext) {
378− // count how many line nos data
379−
380−
381− Stab_Sym *sym, *sym_end;
382− char func_name[128], last_func_name[128];
383− unsigned long func_addr, last_pc, pc;
384− const char *incl_files[INCLUDE_STACK_SIZE];
385− int incl_index, len, last_line_num;
386− const char *str, *p;
387−
388− LINENO CoffLineNo;
389−
390− func_name[0] = '\0';
391− func_addr = 0;
392− incl_index = 0;
393− last_func_name[0] = '\0';
394− last_pc = 0;
395− last_line_num = 1;
396− sym = (Stab_Sym *) stab_section->data + 1;
397− sym_end =
398− (Stab_Sym *) (stab_section->data +
399− stab_section->data_offset);
400−
401− while (sym < sym_end) {
402− switch (sym->n_type) {
403− /* function start or end */
404− case N_FUN:
405− if (sym->n_strx == 0) {
406− // end of function
407−
408− CoffLineNo.l_addr.l_paddr = last_pc;
409− CoffLineNo.l_lnno = last_line_num + 1;
410− fwrite(&CoffLineNo, 6, 1, f);
411−
412− pc = sym->n_value + func_addr;
413− func_name[0] = '\0';
414− func_addr = 0;
415− } else {
416− // beginning of function
417−
418− str =
419− (const char *) stabstr_section->data +
420− sym->n_strx;
421−
422−
423− p = strchr(str, ':');
424− if (!p) {
425− pstrcpy(func_name, sizeof(func_name), str);
426− } else {
427− len = p - str;
428− if (len > sizeof(func_name) - 1)
429− len = sizeof(func_name) - 1;
430− memcpy(func_name, str, len);
431− func_name[len] = '\0';
432− }
433− func_addr = sym->n_value;
434− last_pc = func_addr;
435− last_line_num = -1;
436−
437− // output a function begin
438−
439− CoffLineNo.l_addr.l_symndx =
440− FindCoffSymbolIndex(func_name);
441− CoffLineNo.l_lnno = 0;
442−
443− fwrite(&CoffLineNo, 6, 1, f);
444− }
445− break;
446−
447− /* line number info */
448− case N_SLINE:
449− pc = sym->n_value + func_addr;
450−
451−
452− /* XXX: slow! */
453− strcpy(last_func_name, func_name);
454−
455− // output a line reference
456−
457− CoffLineNo.l_addr.l_paddr = last_pc;
458−
459− if (last_line_num == -1) {
460− CoffLineNo.l_lnno = sym->n_desc;
461− } else {
462− CoffLineNo.l_lnno = last_line_num + 1;
463− }
464−
465− fwrite(&CoffLineNo, 6, 1, f);
466−
467− last_pc = pc;
468− last_line_num = sym->n_desc;
469−
470− break;
471−
472− /* include files */
473− case N_BINCL:
474− str =
475− (const char *) stabstr_section->data + sym->n_strx;
476− add_incl2:
477− if (incl_index < INCLUDE_STACK_SIZE) {
478− incl_files[incl_index++] = str;
479− }
480− break;
481− case N_EINCL:
482− if (incl_index > 1)
483− incl_index--;
484− break;
485− case N_SO:
486− if (sym->n_strx == 0) {
487− incl_index = 0; /* end of translation unit */
488− } else {
489− str =
490− (const char *) stabstr_section->data +
491− sym->n_strx;
492− /* do not add path */
493− len = strlen(str);
494− if (len > 0 && str[len - 1] != '/')
495− goto add_incl2;
496− }
497− break;
498− }
499− sym++;
500− }
501− }
364+ coff_sec = &section_header[i];
365+ tcc_sect = s1->sections[i];
366+
367+ if (s1->do_debug && tcc_sect == stext) {
368+ // count how many line nos data
369+
370+ Stab_Sym* sym, *sym_end;
371+ char func_name[128], last_func_name[128];
372+ unsigned long func_addr, last_pc, pc;
373+ const char* incl_files[INCLUDE_STACK_SIZE];
374+ int incl_index, len, last_line_num;
375+ const char* str, *p;
376+
377+ LINENO CoffLineNo;
378+
379+ func_name[0] = '\0';
380+ func_addr = 0;
381+ incl_index = 0;
382+ last_func_name[0] = '\0';
383+ last_pc = 0;
384+ last_line_num = 1;
385+ sym = (Stab_Sym*)stab_section->data + 1;
386+ sym_end =
387+ (Stab_Sym*)(stab_section->data + stab_section->data_offset);
388+
389+ while (sym < sym_end) {
390+ switch (sym->n_type) {
391+ /* function start or end */
392+ case N_FUN:
393+ if (sym->n_strx == 0) {
394+ // end of function
395+
396+ CoffLineNo.l_addr.l_paddr = last_pc;
397+ CoffLineNo.l_lnno = last_line_num + 1;
398+ fwrite(&CoffLineNo, 6, 1, f);
399+
400+ pc = sym->n_value + func_addr;
401+ func_name[0] = '\0';
402+ func_addr = 0;
403+ } else {
404+ // beginning of function
405+
406+ str = (const char*)stabstr_section->data + sym->n_strx;
407+
408+ p = strchr(str, ':');
409+ if (!p) {
410+ pstrcpy(func_name, sizeof(func_name), str);
411+ } else {
412+ len = p - str;
413+ if (len > sizeof(func_name) - 1)
414+ len = sizeof(func_name) - 1;
415+ memcpy(func_name, str, len);
416+ func_name[len] = '\0';
417+ }
418+ func_addr = sym->n_value;
419+ last_pc = func_addr;
420+ last_line_num = -1;
421+
422+ // output a function begin
423+
424+ CoffLineNo.l_addr.l_symndx =
425+ FindCoffSymbolIndex(func_name);
426+ CoffLineNo.l_lnno = 0;
427+
428+ fwrite(&CoffLineNo, 6, 1, f);
429+ }
430+ break;
431+
432+ /* line number info */
433+ case N_SLINE:
434+ pc = sym->n_value + func_addr;
435+
436+ /* XXX: slow! */
437+ strcpy(last_func_name, func_name);
438+
439+ // output a line reference
440+
441+ CoffLineNo.l_addr.l_paddr = last_pc;
442+
443+ if (last_line_num == -1) {
444+ CoffLineNo.l_lnno = sym->n_desc;
445+ } else {
446+ CoffLineNo.l_lnno = last_line_num + 1;
447+ }
448+
449+ fwrite(&CoffLineNo, 6, 1, f);
450+
451+ last_pc = pc;
452+ last_line_num = sym->n_desc;
453+
454+ break;
455+
456+ /* include files */
457+ case N_BINCL:
458+ str = (const char*)stabstr_section->data + sym->n_strx;
459+ add_incl2:
460+ if (incl_index < INCLUDE_STACK_SIZE) {
461+ incl_files[incl_index++] = str;
462+ }
463+ break;
464+ case N_EINCL:
465+ if (incl_index > 1)
466+ incl_index--;
467+ break;
468+ case N_SO:
469+ if (sym->n_strx == 0) {
470+ incl_index = 0; /* end of translation unit */
471+ } else {
472+ str = (const char*)stabstr_section->data + sym->n_strx;
473+ /* do not add path */
474+ len = strlen(str);
475+ if (len > 0 && str[len - 1] != '/')
476+ goto add_incl2;
477+ }
478+ break;
479+ }
480+ sym++;
481+ }
482+ }
502483 }
503484
504485 // write symbol table
505486 if (s1->do_debug) {
506− int k;
507− struct syment csym;
508− AUXFUNC auxfunc;
509− AUXBF auxbf;
510− AUXEF auxef;
511− int i;
512− Elf32_Sym *p;
513− const char *name;
514− int nstr;
515− int n = 0;
516−
517− Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
518− pCoff_str_table = Coff_str_table;
519− nstr = 0;
520−
521− p = (Elf32_Sym *) symtab_section->data;
522−
523−
524− for (i = 0; i < nb_syms; i++) {
525−
526− name = symtab_section->link->data + p->st_name;
527−
528− for (k = 0; k < 8; k++)
529− csym._n._n_name[k] = 0;
530−
531− if (strlen(name) <= 8) {
532− strcpy(csym._n._n_name, name);
533− } else {
534− if (pCoff_str_table - Coff_str_table + strlen(name) >
535− MAX_STR_TABLE - 1)
536− tcc_error("String table too large");
537−
538− csym._n._n_n._n_zeroes = 0;
539− csym._n._n_n._n_offset =
540− pCoff_str_table - Coff_str_table + 4;
541−
542− strcpy(pCoff_str_table, name);
543− pCoff_str_table += strlen(name) + 1; // skip over null
544− nstr++;
545− }
546−
547− if (p->st_info == 4) {
548− // put a filename symbol
549− csym.n_value = 33; // ?????
550− csym.n_scnum = N_DEBUG;
551− csym.n_type = 0;
552− csym.n_sclass = C_FILE;
553− csym.n_numaux = 0;
554− fwrite(&csym, 18, 1, f);
555− n++;
556−
557− } else if (p->st_info == 0x12) {
558− // find the function data
559−
560− for (k = 0; k < nFuncs; k++) {
561− if (strcmp(name, Func[k]) == 0)
562− break;
563− }
564−
565− if (k >= nFuncs) {
566− tcc_error("debug info can't find function: %s", name);
567− }
568− // put a Function Name
569−
570− csym.n_value = p->st_value; // physical address
571− csym.n_scnum = CoffTextSectionNo;
572− csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
573− csym.n_sclass = C_EXT;
574− csym.n_numaux = 1;
575− fwrite(&csym, 18, 1, f);
576−
577− // now put aux info
578−
579− auxfunc.tag = 0;
580− auxfunc.size = EndAddress[k] - p->st_value;
581− auxfunc.fileptr = LineNoFilePtr[k];
582− auxfunc.nextsym = n + 6; // tktk
583− auxfunc.dummy = 0;
584− fwrite(&auxfunc, 18, 1, f);
585−
586− // put a .bf
587−
588− strcpy(csym._n._n_name, ".bf");
589− csym.n_value = p->st_value; // physical address
590− csym.n_scnum = CoffTextSectionNo;
591− csym.n_type = 0;
592− csym.n_sclass = C_FCN;
593− csym.n_numaux = 1;
594− fwrite(&csym, 18, 1, f);
595−
596− // now put aux info
597−
598− auxbf.regmask = 0;
599− auxbf.lineno = 0;
600− auxbf.nentries = FuncEntries[k];
601− auxbf.localframe = 0;
602− auxbf.nextentry = n + 6;
603− auxbf.dummy = 0;
604− fwrite(&auxbf, 18, 1, f);
605−
606− // put a .ef
607−
608− strcpy(csym._n._n_name, ".ef");
609− csym.n_value = EndAddress[k]; // physical address
610− csym.n_scnum = CoffTextSectionNo;
611− csym.n_type = 0;
612− csym.n_sclass = C_FCN;
613− csym.n_numaux = 1;
614− fwrite(&csym, 18, 1, f);
615−
616− // now put aux info
617−
618− auxef.dummy = 0;
619− auxef.lineno = LastLineNo[k];
620− auxef.dummy1 = 0;
621− auxef.dummy2 = 0;
622− auxef.dummy3 = 0;
623− auxef.dummy4 = 0;
624− fwrite(&auxef, 18, 1, f);
625−
626− n += 6;
627−
628− } else {
629− // try an put some type info
630−
631− if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
632− csym.n_type = T_DOUBLE; // int
633− csym.n_sclass = C_EXT;
634− } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
635− csym.n_type = T_FLOAT;
636− csym.n_sclass = C_EXT;
637− } else if ((p->st_other & VT_BTYPE) == VT_INT) {
638− csym.n_type = T_INT; // int
639− csym.n_sclass = C_EXT;
640− } else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
641− csym.n_type = T_SHORT;
642− csym.n_sclass = C_EXT;
643− } else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
644− csym.n_type = T_CHAR;
645− csym.n_sclass = C_EXT;
646− } else {
647− csym.n_type = T_INT; // just mark as a label
648− csym.n_sclass = C_LABEL;
649− }
650−
651−
652− csym.n_value = p->st_value;
653− csym.n_scnum = 2;
654− csym.n_numaux = 1;
655− fwrite(&csym, 18, 1, f);
656−
657− auxfunc.tag = 0;
658− auxfunc.size = 0x20;
659− auxfunc.fileptr = 0;
660− auxfunc.nextsym = 0;
661− auxfunc.dummy = 0;
662− fwrite(&auxfunc, 18, 1, f);
663− n++;
664− n++;
665−
666− }
667−
668− p++;
669− }
487+ int k;
488+ struct syment csym;
489+ AUXFUNC auxfunc;
490+ AUXBF auxbf;
491+ AUXEF auxef;
492+ int i;
493+ Elf32_Sym* p;
494+ const char* name;
495+ int nstr;
496+ int n = 0;
497+
498+ Coff_str_table = (char*)tcc_malloc(MAX_STR_TABLE);
499+ pCoff_str_table = Coff_str_table;
500+ nstr = 0;
501+
502+ p = (Elf32_Sym*)symtab_section->data;
503+
504+ for (i = 0; i < nb_syms; i++) {
505+
506+ name = symtab_section->link->data + p->st_name;
507+
508+ for (k = 0; k < 8; k++)
509+ csym._n._n_name[k] = 0;
510+
511+ if (strlen(name) <= 8) {
512+ strcpy(csym._n._n_name, name);
513+ } else {
514+ if (pCoff_str_table - Coff_str_table + strlen(name) >
515+ MAX_STR_TABLE - 1)
516+ tcc_error("String table too large");
517+
518+ csym._n._n_n._n_zeroes = 0;
519+ csym._n._n_n._n_offset = pCoff_str_table - Coff_str_table + 4;
520+
521+ strcpy(pCoff_str_table, name);
522+ pCoff_str_table += strlen(name) + 1; // skip over null
523+ nstr++;
524+ }
525+
526+ if (p->st_info == 4) {
527+ // put a filename symbol
528+ csym.n_value = 33; // ?????
529+ csym.n_scnum = N_DEBUG;
530+ csym.n_type = 0;
531+ csym.n_sclass = C_FILE;
532+ csym.n_numaux = 0;
533+ fwrite(&csym, 18, 1, f);
534+ n++;
535+
536+ } else if (p->st_info == 0x12) {
537+ // find the function data
538+
539+ for (k = 0; k < nFuncs; k++) {
540+ if (strcmp(name, Func[k]) == 0)
541+ break;
542+ }
543+
544+ if (k >= nFuncs) {
545+ tcc_error("debug info can't find function: %s", name);
546+ }
547+ // put a Function Name
548+
549+ csym.n_value = p->st_value; // physical address
550+ csym.n_scnum = CoffTextSectionNo;
551+ csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
552+ csym.n_sclass = C_EXT;
553+ csym.n_numaux = 1;
554+ fwrite(&csym, 18, 1, f);
555+
556+ // now put aux info
557+
558+ auxfunc.tag = 0;
559+ auxfunc.size = EndAddress[k] - p->st_value;
560+ auxfunc.fileptr = LineNoFilePtr[k];
561+ auxfunc.nextsym = n + 6; // tktk
562+ auxfunc.dummy = 0;
563+ fwrite(&auxfunc, 18, 1, f);
564+
565+ // put a .bf
566+
567+ strcpy(csym._n._n_name, ".bf");
568+ csym.n_value = p->st_value; // physical address
569+ csym.n_scnum = CoffTextSectionNo;
570+ csym.n_type = 0;
571+ csym.n_sclass = C_FCN;
572+ csym.n_numaux = 1;
573+ fwrite(&csym, 18, 1, f);
574+
575+ // now put aux info
576+
577+ auxbf.regmask = 0;
578+ auxbf.lineno = 0;
579+ auxbf.nentries = FuncEntries[k];
580+ auxbf.localframe = 0;
581+ auxbf.nextentry = n + 6;
582+ auxbf.dummy = 0;
583+ fwrite(&auxbf, 18, 1, f);
584+
585+ // put a .ef
586+
587+ strcpy(csym._n._n_name, ".ef");
588+ csym.n_value = EndAddress[k]; // physical address
589+ csym.n_scnum = CoffTextSectionNo;
590+ csym.n_type = 0;
591+ csym.n_sclass = C_FCN;
592+ csym.n_numaux = 1;
593+ fwrite(&csym, 18, 1, f);
594+
595+ // now put aux info
596+
597+ auxef.dummy = 0;
598+ auxef.lineno = LastLineNo[k];
599+ auxef.dummy1 = 0;
600+ auxef.dummy2 = 0;
601+ auxef.dummy3 = 0;
602+ auxef.dummy4 = 0;
603+ fwrite(&auxef, 18, 1, f);
604+
605+ n += 6;
606+
607+ } else {
608+ // try an put some type info
609+
610+ if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
611+ csym.n_type = T_DOUBLE; // int
612+ csym.n_sclass = C_EXT;
613+ } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
614+ csym.n_type = T_FLOAT;
615+ csym.n_sclass = C_EXT;
616+ } else if ((p->st_other & VT_BTYPE) == VT_INT) {
617+ csym.n_type = T_INT; // int
618+ csym.n_sclass = C_EXT;
619+ } else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
620+ csym.n_type = T_SHORT;
621+ csym.n_sclass = C_EXT;
622+ } else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
623+ csym.n_type = T_CHAR;
624+ csym.n_sclass = C_EXT;
625+ } else {
626+ csym.n_type = T_INT; // just mark as a label
627+ csym.n_sclass = C_LABEL;
628+ }
629+
630+ csym.n_value = p->st_value;
631+ csym.n_scnum = 2;
632+ csym.n_numaux = 1;
633+ fwrite(&csym, 18, 1, f);
634+
635+ auxfunc.tag = 0;
636+ auxfunc.size = 0x20;
637+ auxfunc.fileptr = 0;
638+ auxfunc.nextsym = 0;
639+ auxfunc.dummy = 0;
640+ fwrite(&auxfunc, 18, 1, f);
641+ n++;
642+ n++;
643+ }
644+
645+ p++;
646+ }
670647 }
671648
672649 if (s1->do_debug) {
673− // write string table
650+ // write string table
674651
675− // first write the size
676− i = pCoff_str_table - Coff_str_table;
677− fwrite(&i, 4, 1, f);
652+ // first write the size
653+ i = pCoff_str_table - Coff_str_table;
654+ fwrite(&i, 4, 1, f);
678655
679− // then write the strings
680− fwrite(Coff_str_table, i, 1, f);
656+ // then write the strings
657+ fwrite(Coff_str_table, i, 1, f);
681658
682− tcc_free(Coff_str_table);
659+ tcc_free(Coff_str_table);
683660 }
684661
685662 return 0;
686663 }
687664
688−
689−
690665 // group the symbols in order of filename, func1, func2, etc
691666 // finally global symbols
692667
693668 void SortSymbolTable(void)
694669 {
695670 int i, j, k, n = 0;
696− Elf32_Sym *p, *p2, *NewTable;
697− char *name, *name2;
698−
699− NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
671+ Elf32_Sym* p, *p2, *NewTable;
672+ char* name, *name2;
700673
701− p = (Elf32_Sym *) symtab_section->data;
674+ NewTable = (Elf32_Sym*)tcc_malloc(nb_syms * sizeof(Elf32_Sym));
702675
676+ p = (Elf32_Sym*)symtab_section->data;
703677
704678 // find a file symbol, copy it over
705679 // then scan the whole symbol list and copy any function
706680 // symbols that match the file association
707681
708682 for (i = 0; i < nb_syms; i++) {
709− if (p->st_info == 4) {
710− name = (char *) symtab_section->link->data + p->st_name;
683+ if (p->st_info == 4) {
684+ name = (char*)symtab_section->link->data + p->st_name;
711685
712− // this is a file symbol, copy it over
686+ // this is a file symbol, copy it over
713687
714− NewTable[n++] = *p;
688+ NewTable[n++] = *p;
715689
716− p2 = (Elf32_Sym *) symtab_section->data;
690+ p2 = (Elf32_Sym*)symtab_section->data;
717691
718− for (j = 0; j < nb_syms; j++) {
719− if (p2->st_info == 0x12) {
720− // this is a func symbol
692+ for (j = 0; j < nb_syms; j++) {
693+ if (p2->st_info == 0x12) {
694+ // this is a func symbol
721695
722− name2 =
723− (char *) symtab_section->link->data + p2->st_name;
696+ name2 = (char*)symtab_section->link->data + p2->st_name;
724697
725− // find the function data index
698+ // find the function data index
726699
727− for (k = 0; k < nFuncs; k++) {
728− if (strcmp(name2, Func[k]) == 0)
729− break;
730− }
700+ for (k = 0; k < nFuncs; k++) {
701+ if (strcmp(name2, Func[k]) == 0)
702+ break;
703+ }
731704
732− if (k >= nFuncs) {
733− tcc_error("debug (sort) info can't find function: %s", name2);
734− }
705+ if (k >= nFuncs) {
706+ tcc_error("debug (sort) info can't find function: %s",
707+ name2);
708+ }
735709
736− if (strcmp(AssociatedFile[k], name) == 0) {
737− // yes they match copy it over
710+ if (strcmp(AssociatedFile[k], name) == 0) {
711+ // yes they match copy it over
738712
739− NewTable[n++] = *p2;
740− }
741− }
742− p2++;
743− }
744− }
745− p++;
713+ NewTable[n++] = *p2;
714+ }
715+ }
716+ p2++;
717+ }
718+ }
719+ p++;
746720 }
747721
748722 // now all the filename and func symbols should have been copied over
749723 // copy all the rest over (all except file and funcs)
750724
751− p = (Elf32_Sym *) symtab_section->data;
725+ p = (Elf32_Sym*)symtab_section->data;
752726 for (i = 0; i < nb_syms; i++) {
753− if (p->st_info != 4 && p->st_info != 0x12) {
754− NewTable[n++] = *p;
755− }
756− p++;
727+ if (p->st_info != 4 && p->st_info != 0x12) {
728+ NewTable[n++] = *p;
729+ }
730+ p++;
757731 }
758732
759733 if (n != nb_syms)
760− tcc_error("Internal Compiler error, debug info");
734+ tcc_error("Internal Compiler error, debug info");
761735
762736 // copy it all back
763737
764− p = (Elf32_Sym *) symtab_section->data;
738+ p = (Elf32_Sym*)symtab_section->data;
765739 for (i = 0; i < nb_syms; i++) {
766− *p++ = NewTable[i];
740+ *p++ = NewTable[i];
767741 }
768742
769743 tcc_free(NewTable);
770744 }
771745
772−
773−int FindCoffSymbolIndex(const char *func_name)
746+int FindCoffSymbolIndex(const char* func_name)
774747 {
775748 int i, n = 0;
776− Elf32_Sym *p;
777− char *name;
749+ Elf32_Sym* p;
750+ char* name;
778751
779− p = (Elf32_Sym *) symtab_section->data;
752+ p = (Elf32_Sym*)symtab_section->data;
780753
781754 for (i = 0; i < nb_syms; i++) {
782755
783− name = (char *) symtab_section->link->data + p->st_name;
756+ name = (char*)symtab_section->link->data + p->st_name;
784757
785− if (p->st_info == 4) {
786− // put a filename symbol
787− n++;
788− } else if (p->st_info == 0x12) {
758+ if (p->st_info == 4) {
759+ // put a filename symbol
760+ n++;
761+ } else if (p->st_info == 0x12) {
789762
790− if (strcmp(func_name, name) == 0)
791− return n;
763+ if (strcmp(func_name, name) == 0)
764+ return n;
792765
793− n += 6;
766+ n += 6;
794767
795− // put a Function Name
768+ // put a Function Name
796769
797− // now put aux info
770+ // now put aux info
798771
799− // put a .bf
772+ // put a .bf
800773
801− // now put aux info
774+ // now put aux info
802775
803− // put a .ef
776+ // put a .ef
804777
805− // now put aux info
778+ // now put aux info
806779
807− } else {
808− n += 2;
809− }
780+ } else {
781+ n += 2;
782+ }
810783
811− p++;
784+ p++;
812785 }
813786
814− return n; // total number of symbols
787+ return n; // total number of symbols
815788 }
816789
817−int OutputTheSection(Section * sect)
790+int OutputTheSection(Section* sect)
818791 {
819− const char *s = sect->name;
792+ const char* s = sect->name;
820793
821794 if (!strcmp(s, ".text"))
822− return 1;
795+ return 1;
823796 else if (!strcmp(s, ".data"))
824− return 1;
797+ return 1;
825798 else
826− return 0;
799+ return 0;
827800 }
828801
829−short int GetCoffFlags(const char *s)
802+short int GetCoffFlags(const char* s)
830803 {
831804 if (!strcmp(s, ".text"))
832− return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
805+ return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
833806 else if (!strcmp(s, ".data"))
834− return STYP_DATA;
807+ return STYP_DATA;
835808 else if (!strcmp(s, ".bss"))
836− return STYP_BSS;
809+ return STYP_BSS;
837810 else if (!strcmp(s, ".stack"))
838− return STYP_BSS | STYP_ALIGN | 0x200;
811+ return STYP_BSS | STYP_ALIGN | 0x200;
839812 else if (!strcmp(s, ".cinit"))
840− return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
813+ return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
841814 else
842− return 0;
815+ return 0;
843816 }
844817
845−Section *FindSection(TCCState * s1, const char *sname)
818+Section* FindSection(TCCState* s1, const char* sname)
846819 {
847− Section *s;
820+ Section* s;
848821 int i;
849822
850823 for (i = 1; i < s1->nb_sections; i++) {
851− s = s1->sections[i];
824+ s = s1->sections[i];
852825
853− if (!strcmp(sname, s->name))
854− return s;
826+ if (!strcmp(sname, s->name))
827+ return s;
855828 }
856829
857830 tcc_error("could not find section %s", sname);
858831 return 0;
859832 }
860833
861−ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
834+ST_FUNC int tcc_load_coff(TCCState* s1, int fd)
862835 {
863−// tktk TokenSym *ts;
836+ // tktk TokenSym *ts;
864837
865− FILE *f;
838+ FILE* f;
866839 unsigned int str_size;
867− char *Coff_str_table, *name;
840+ char* Coff_str_table, *name;
868841 int i, k;
869842 struct syment csym;
870843 char name2[9];
871− FILHDR file_hdr; /* FILE HEADER STRUCTURE */
844+ FILHDR file_hdr; /* FILE HEADER STRUCTURE */
872845
873846 f = fdopen(fd, "rb");
874847 if (!f) {
875− tcc_error("Unable to open .out file for input");
848+ tcc_error("Unable to open .out file for input");
876849 }
877850
878851 if (fread(&file_hdr, FILHSZ, 1, f) != 1)
879− tcc_error("error reading .out file for input");
852+ tcc_error("error reading .out file for input");
880853
881854 if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
882− tcc_error("error reading .out file for input");
855+ tcc_error("error reading .out file for input");
883856
884857 // first read the string table
885858
886859 if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
887− tcc_error("error reading .out file for input");
860+ tcc_error("error reading .out file for input");
888861
889862 if (fread(&str_size, sizeof(int), 1, f) != 1)
890− tcc_error("error reading .out file for input");
891−
863+ tcc_error("error reading .out file for input");
892864
893− Coff_str_table = (char *) tcc_malloc(str_size);
865+ Coff_str_table = (char*)tcc_malloc(str_size);
894866
895867 if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
896− tcc_error("error reading .out file for input");
868+ tcc_error("error reading .out file for input");
897869
898870 // read/process all the symbols
899871
900872 // seek back to symbols
901873
902874 if (fseek(f, file_hdr.f_symptr, SEEK_SET))
903− tcc_error("error reading .out file for input");
875+ tcc_error("error reading .out file for input");
904876
905877 for (i = 0; i < file_hdr.f_nsyms; i++) {
906− if (fread(&csym, SYMESZ, 1, f) != 1)
907− tcc_error("error reading .out file for input");
908−
909− if (csym._n._n_n._n_zeroes == 0) {
910− name = Coff_str_table + csym._n._n_n._n_offset - 4;
911− } else {
912− name = csym._n._n_name;
913−
914− if (name[7] != 0) {
915− for (k = 0; k < 8; k++)
916− name2[k] = name[k];
917−
918− name2[8] = 0;
919−
920− name = name2;
921− }
922− }
923−// if (strcmp("_DAC_Buffer",name)==0) // tktk
924−// name[0]=0;
925−
926− if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
927− (csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
928− (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
929− (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
930− {
931− // strip off any leading underscore (except for other main routine)
932−
933− if (name[0] == '_' && strcmp(name, "_main") != 0)
934− name++;
935−
936− tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
937− }
938− // skip any aux records
939−
940− if (csym.n_numaux == 1) {
941− if (fread(&csym, SYMESZ, 1, f) != 1)
942− tcc_error("error reading .out file for input");
943− i++;
944− }
878+ if (fread(&csym, SYMESZ, 1, f) != 1)
879+ tcc_error("error reading .out file for input");
880+
881+ if (csym._n._n_n._n_zeroes == 0) {
882+ name = Coff_str_table + csym._n._n_n._n_offset - 4;
883+ } else {
884+ name = csym._n._n_name;
885+
886+ if (name[7] != 0) {
887+ for (k = 0; k < 8; k++)
888+ name2[k] = name[k];
889+
890+ name2[8] = 0;
891+
892+ name = name2;
893+ }
894+ }
895+ // if (strcmp("_DAC_Buffer",name)==0) // tktk
896+ // name[0]=0;
897+
898+ if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) ||
899+ ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) ||
900+ (csym.n_type == 0x4 && csym.n_sclass == 0x2) ||
901+ (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
902+ (csym.n_type == 0x18 &&
903+ csym.n_sclass == 0x2) || // pointer to structure
904+ (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
905+ (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
906+ {
907+ // strip off any leading underscore (except for other main routine)
908+
909+ if (name[0] == '_' && strcmp(name, "_main") != 0)
910+ name++;
911+
912+ tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
913+ }
914+ // skip any aux records
915+
916+ if (csym.n_numaux == 1) {
917+ if (fread(&csym, SYMESZ, 1, f) != 1)
918+ tcc_error("error reading .out file for input");
919+ i++;
920+ }
945921 }
946922
947923 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t