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

They now mostly follow the same coding style as everything else.
This commit is contained in:
gus knight 2015-07-27 14:26:15 -04:00
parent 9e1b6bf517
commit 694d0fdade
2 changed files with 2082 additions and 2067 deletions

187
arm-gen.c
View file

@ -183,9 +183,11 @@ ST_FUNC void arm_init(struct TCCState *s)
float_type.t = VT_FLOAT; float_type.t = VT_FLOAT;
double_type.t = VT_DOUBLE; double_type.t = VT_DOUBLE;
func_float_type.t = VT_FUNC; func_float_type.t = VT_FUNC;
func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD); func_float_type.ref =
sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
func_double_type.t = VT_FUNC; func_double_type.t = VT_FUNC;
func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD); func_double_type.ref =
sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
float_abi = s->float_abi; float_abi = s->float_abi;
#ifndef TCC_ARM_HARDFLOAT #ifndef TCC_ARM_HARDFLOAT
@ -209,11 +211,13 @@ ST_FUNC void arm_init(struct TCCState *s)
} }
#endif #endif
static int two2mask(int a,int b) { static int two2mask(int a, int b)
{
return (reg_classes[a] | reg_classes[b]) & ~(RC_INT | RC_FLOAT); return (reg_classes[a] | reg_classes[b]) & ~(RC_INT | RC_FLOAT);
} }
static int regmask(int r) { static int regmask(int r)
{
return reg_classes[r] & ~(RC_INT | RC_FLOAT); return reg_classes[r] & ~(RC_INT | RC_FLOAT);
} }
@ -254,8 +258,7 @@ static uint32_t stuff_const(uint32_t op, uint32_t c)
int try_neg = 0; int try_neg = 0;
uint32_t nc = 0, negop = 0; uint32_t nc = 0, negop = 0;
switch(op&0x1F00000) switch (op & 0x1F00000) {
{
case 0x800000: // add case 0x800000: // add
case 0x400000: // sub case 0x400000: // sub
try_neg = 1; try_neg = 1;
@ -301,9 +304,9 @@ static uint32_t stuff_const(uint32_t op, uint32_t c)
return 0; return 0;
} }
// only add,sub // only add,sub
void stuff_const_harder(uint32_t op, uint32_t v) { void stuff_const_harder(uint32_t op, uint32_t v)
{
uint32_t x; uint32_t x;
x = stuff_const(op, v); x = stuff_const(op, v);
if (x) if (x)
@ -312,7 +315,8 @@ void stuff_const_harder(uint32_t op, uint32_t v) {
uint32_t a[16], nv, no, o2, n2; uint32_t a[16], nv, no, o2, n2;
int i, j, k; int i, j, k;
a[0] = 0xff; a[0] = 0xff;
o2=(op&0xfff0ffff)|((op&0xf000)<<4);; o2 = (op & 0xfff0ffff) | ((op & 0xf000) << 4);
;
for (i = 1; i < 16; i++) for (i = 1; i < 16; i++)
a[i] = (a[i - 1] >> 2) | (a[i - 1] << 30); a[i] = (a[i - 1] >> 2) | (a[i - 1] << 30);
for (i = 0; i < 12; i++) for (i = 0; i < 12; i++)
@ -428,7 +432,8 @@ static uint32_t intr(int r)
return r; return r;
} }
static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift) static void calcaddr(uint32_t* base, int* off, int* sgn, int maxoff,
unsigned shift)
{ {
if (*off > maxoff || *off & ((1 << shift) - 1)) { if (*off > maxoff || *off & ((1 << shift) - 1)) {
uint32_t x, y; uint32_t x, y;
@ -457,8 +462,7 @@ static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned sh
static uint32_t mapcc(int cc) static uint32_t mapcc(int cc)
{ {
switch(cc) switch (cc) {
{
case TOK_ULT: case TOK_ULT:
return 0x30000000; /* CC/LO */ return 0x30000000; /* CC/LO */
case TOK_UGE: case TOK_UGE:
@ -490,8 +494,7 @@ static uint32_t mapcc(int cc)
static int negcc(int cc) static int negcc(int cc)
{ {
switch(cc) switch (cc) {
{
case TOK_ULT: case TOK_ULT:
return TOK_UGE; return TOK_UGE;
case TOK_UGE: case TOK_UGE:
@ -587,8 +590,8 @@ void load(int r, SValue *sv)
#endif #endif
o(op | (fpr(r) << 12) | (fc >> 2) | (base << 16)); o(op | (fpr(r) << 12) | (fc >> 2) | (base << 16));
#endif #endif
} else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE } else if ((ft & (VT_BTYPE | VT_UNSIGNED)) == VT_BYTE ||
|| (ft & VT_BTYPE) == VT_SHORT) { (ft & VT_BTYPE) == VT_SHORT) {
calcaddr(&base, &fc, &sign, 255, 0); calcaddr(&base, &fc, &sign, 255, 0);
op = 0xE1500090; op = 0xE1500090;
if ((ft & VT_BTYPE) == VT_SHORT) if ((ft & VT_BTYPE) == VT_SHORT)
@ -597,7 +600,8 @@ void load(int r, SValue *sv)
op |= 0x40; op |= 0x40;
if (!sign) if (!sign)
op |= 0x800000; op |= 0x800000;
o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); o(op | (intr(r) << 12) | (base << 16) | ((fc & 0xf0) << 4) |
(fc & 0xf));
} else { } else {
calcaddr(&base, &fc, &sign, 4095, 0); calcaddr(&base, &fc, &sign, 4095, 0);
op = 0xE5100000; op = 0xE5100000;
@ -648,7 +652,8 @@ void load(int r, SValue *sv)
} else if (v < VT_CONST) { } else if (v < VT_CONST) {
if (is_float(ft)) if (is_float(ft))
#ifdef TCC_ARM_VFP #ifdef TCC_ARM_VFP
o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */ o(0xEEB00A40 | (vfpr(r) << 12) | vfpr(v) |
T2CPR(ft)); /* fcpyX */
#else #else
o(0xEE008180 | (fpr(r) << 12) | fpr(v)); o(0xEE008180 | (fpr(r) << 12) | fpr(v));
#endif #endif
@ -725,7 +730,8 @@ void store(int r, SValue *sv)
op = 0xE14000B0; op = 0xE14000B0;
if (!sign) if (!sign)
op |= 0x800000; op |= 0x800000;
o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); o(op | (intr(r) << 12) | (base << 16) | ((fc & 0xf0) << 4) |
(fc & 0xf));
} else { } else {
calcaddr(&base, &fc, &sign, 4095, 0); calcaddr(&base, &fc, &sign, 4095, 0);
op = 0xE5000000; op = 0xE5000000;
@ -759,7 +765,8 @@ static void gcall_or_jmp(int is_jmp)
/* relocation case */ /* relocation case */
greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
} else } else
put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0); put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24,
0);
o(x | (is_jmp ? 0xE0000000 : 0xE1000000)); o(x | (is_jmp ? 0xE0000000 : 0xE1000000));
} else { } else {
if (!is_jmp) if (!is_jmp)
@ -792,7 +799,9 @@ static int is_hgen_float_aggr(CType *type)
ref = type->ref->next; ref = type->ref->next;
btype = ref->type.t & VT_BTYPE; btype = ref->type.t & VT_BTYPE;
if (btype == VT_FLOAT || btype == VT_DOUBLE) { if (btype == VT_FLOAT || btype == VT_DOUBLE) {
for(; ref && btype == (ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++); for (; ref && btype == (ref->type.t & VT_BTYPE);
ref = ref->next, nb_fields++)
;
return !ref && nb_fields <= 4; return !ref && nb_fields <= 4;
} }
} }
@ -800,7 +809,8 @@ static int is_hgen_float_aggr(CType *type)
} }
struct avail_regs { struct avail_regs {
signed char avail[3]; /* 3 holes max with only float and double alignments */ signed char
avail[3]; /* 3 holes max with only float and double alignments */
int first_hole; /* first available hole */ int first_hole; /* first available hole */
int last_hole; /* last available hole (none if equal to first_hole) */ int last_hole; /* last available hole (none if equal to first_hole) */
int first_free_reg; /* next free register in the sequence, hole excluded */ int first_free_reg; /* next free register in the sequence, hole excluded */
@ -876,7 +886,9 @@ ST_FUNC int regargs_nregs(RegArgs *args)
/* Return the number of registers needed to return the struct, or 0 if /* Return the number of registers needed to return the struct, or 0 if
returning via struct pointer. */ returning via struct pointer. */
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize, RegArgs *args) { ST_FUNC int gfunc_sret(CType* vt, int variadic, CType* ret, int* ret_align,
int* regsize, RegArgs* args)
{
#ifdef TCC_ARM_EABI #ifdef TCC_ARM_EABI
int size, align; int size, align;
size = type_size(vt, &align); size = type_size(vt, &align);
@ -929,7 +941,8 @@ struct param_plan {
struct plan { struct plan {
struct param_plan* pplans; /* array of all the param plans */ struct param_plan* pplans; /* array of all the param plans */
struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */ struct param_plan*
clsplans[NB_CLASSES]; /* per class lists of param plans */
}; };
#define add_param_plan(plan, pplan, class) \ #define add_param_plan(plan, pplan, class) \
@ -959,7 +972,8 @@ struct plan {
static int assign_regs(int nb_args, int float_abi, struct plan* plan, int* todo) static int assign_regs(int nb_args, int float_abi, struct plan* plan, int* todo)
{ {
int i, size, align; int i, size, align;
int ncrn /* next core register number */, nsaa /* next stacked argument address*/; int ncrn /* next core register number */,
nsaa /* next stacked argument address*/;
int plan_nb = 0; int plan_nb = 0;
struct param_plan pplan; struct param_plan pplan;
struct avail_regs avregs = AVAIL_REGS_INITIALIZER; struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
@ -983,14 +997,15 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
if (float_abi == ARM_HARD_FLOAT) { if (float_abi == ARM_HARD_FLOAT) {
int is_hfa = 0; /* Homogeneous float aggregate */ int is_hfa = 0; /* Homogeneous float aggregate */
if (is_float(vtop[-i].type.t) if (is_float(vtop[-i].type.t) ||
|| (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) { (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
int end_vfpreg; int end_vfpreg;
start_vfpreg = assign_vfpreg(&avregs, align, size); start_vfpreg = assign_vfpreg(&avregs, align, size);
end_vfpreg = start_vfpreg + ((size - 1) >> 2); end_vfpreg = start_vfpreg + ((size - 1) >> 2);
if (start_vfpreg >= 0) { if (start_vfpreg >= 0) {
pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]}; pplan = (struct param_plan){start_vfpreg, end_vfpreg,
&vtop[-i]};
if (is_hfa) if (is_hfa)
add_param_plan(plan, pplan, VFP_STRUCT_CLASS); add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
else else
@ -1002,7 +1017,8 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
} }
ncrn = (ncrn + (align - 1) / 4) & ~((align / 4) - 1); ncrn = (ncrn + (align - 1) / 4) & ~((align / 4) - 1);
if (ncrn + size / 4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) { if (ncrn + size / 4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
/* The parameter is allocated both in core register and on stack. As /* The parameter is allocated both in core register and on
* stack. As
* such, it can be of either class: it would either be the last of * such, it can be of either class: it would either be the last of
* CORE_STRUCT_CLASS or the first of STACK_CLASS. */ * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
for (j = ncrn; j < 4 && j < ncrn + size / 4; j++) for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
@ -1064,11 +1080,12 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
It is thus important that: It is thus important that:
- structures assigned to core regs must be copied after parameters - structures assigned to core regs must be copied after parameters
assigned to the stack but before structures assigned to VFP regs because assigned to the stack but before structures assigned to VFP regs
a structure can lie partly in core registers and partly on the stack; because a structure can lie partly in core registers and partly on
the stack;
- parameters assigned to the stack and all structures be copied before - parameters assigned to the stack and all structures be copied before
parameters assigned to a core reg since copying a parameter to the stack parameters assigned to a core reg since copying a parameter to the
require using a core reg; stack require using a core reg;
- parameters assigned to VFP regs be copied before structures assigned to - parameters assigned to VFP regs be copied before structures assigned to
VFP regs as the copy might use an even numbered VFP reg that already VFP regs as the copy might use an even numbered VFP reg that already
holds part of a structure. */ holds part of a structure. */
@ -1092,21 +1109,23 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
gadd_sp(-size); gadd_sp(-size);
/* generate structure store */ /* generate structure store */
r = get_reg(RC_INT); r = get_reg(RC_INT);
o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */ o(0xE28D0000 | (intr(r) << 12) |
padding); /* add r, sp, padding */
vset(&vtop->type, r | VT_LVAL, 0); vset(&vtop->type, r | VT_LVAL, 0);
vswap(); vswap();
vstore(); /* memcpy to current sp + potential padding */ vstore(); /* memcpy to current sp + potential padding */
/* Homogeneous float aggregate are loaded to VFP registers /* Homogeneous float aggregate are loaded to VFP registers
immediately since there is no way of loading data in multiple immediately since there is no way of loading data in
non consecutive VFP registers as what is done for other multiple non consecutive VFP registers as what is done
structures (see the use of todo). */ for other structures (see the use of todo). */
if (i == VFP_STRUCT_CLASS) { if (i == VFP_STRUCT_CLASS) {
int first = pplan->start, nb = pplan->end - first + 1; int first = pplan->start, nb = pplan->end - first + 1;
/* vpop.32 {pplan->start, ..., pplan->end} */ /* vpop.32 {pplan->start, ..., pplan->end} */
o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb); o(0xECBD0A00 | (first & 1) << 22 | (first >> 1) << 12 |
/* No need to write the register used to a SValue since VFP regs nb);
cannot be used for gcall_or_jmp */ /* No need to write the register used to a SValue since
VFP regs cannot be used for gcall_or_jmp */
} }
} else { } else {
if (is_float(pplan->sval->type.t)) { if (is_float(pplan->sval->type.t)) {
@ -1150,15 +1169,20 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
o(0xE52D0004 | (intr(r) << 12)); /* push r */ o(0xE52D0004 | (intr(r) << 12)); /* push r */
} }
if (i == STACK_CLASS && pplan->prev) if (i == STACK_CLASS && pplan->prev)
gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */ gadd_sp(pplan->prev->end -
pplan->start); /* Add padding if any */
} }
break; break;
case VFP_CLASS: case VFP_CLASS:
gv(regmask(TREG_F0 + (pplan->start >> 1))); gv(regmask(TREG_F0 + (pplan->start >> 1)));
if (pplan->start & 1) { /* Must be in upper part of double register */ if (pplan->start &
o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */ 1) { /* Must be in upper part of double register */
vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */ o(0xEEF00A40 | ((pplan->start >> 1) << 12) |
(pplan->start >> 1)); /* vmov.f32 s(n+1), sn */
vtop->r =
VT_CONST; /* avoid being saved on stack by gv for next
float */
} }
break; break;
@ -1185,13 +1209,14 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
if (todo) { if (todo) {
o(0xE8BD0000 | todo); /* pop {todo} */ o(0xE8BD0000 | todo); /* pop {todo} */
for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) { for (pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan;
pplan = pplan->prev) {
int r; int r;
pplan->sval->r = pplan->start; pplan->sval->r = pplan->start;
/* An SValue can only pin 2 registers at best (r and r2) but a structure /* An SValue can only pin 2 registers at best (r and r2) but a
can occupy more than 2 registers. Thus, we need to push on the value structure can occupy more than 2 registers. Thus, we need to
stack some fake parameter to have on SValue for each registers used push on the value stack some fake parameter to have on SValue
by a structure (r2 is not used). */ for each registers used by a structure (r2 is not used). */
for (r = pplan->start + 1; r <= pplan->end; r++) { for (r = pplan->start + 1; r <= pplan->end; r++) {
if (todo & (1 << r)) { if (todo & (1 << r)) {
nb_extra_sval++; nb_extra_sval++;
@ -1223,9 +1248,9 @@ void gfunc_call(int nb_args)
float_abi = ARM_SOFTFP_FLOAT; float_abi = ARM_SOFTFP_FLOAT;
} }
#endif #endif
/* cannot let cpu flags if other instruction are generated. Also avoid leaving /* cannot let cpu flags if other instruction are generated. Also avoid
VT_JMP anywhere except on the top of the stack because it would complicate leaving VT_JMP anywhere except on the top of the stack because it
the code generator. */ would complicate the code generator. */
r = vtop->r & VT_VALMASK; r = vtop->r & VT_VALMASK;
if (r == VT_CMP || (r & ~1) == VT_JMP) if (r == VT_CMP || (r & ~1) == VT_JMP)
gv(RC_INT); gv(RC_INT);
@ -1258,7 +1283,8 @@ void gfunc_call(int nb_args)
} }
#endif #endif
vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ leaffunc =
0; /* we are calling a function, so we aren't in a leaf function */
float_abi = def_float_abi; float_abi = def_float_abi;
} }
@ -1281,8 +1307,7 @@ void gfunc_prolog(CType *func_type)
n = nf = 0; n = nf = 0;
if ((func_vt.t & VT_BTYPE) == VT_STRUCT && if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
!gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs, &dummy)) !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs, &dummy)) {
{
n++; n++;
struct_ret = 1; struct_ret = 1;
func_vc = 12; /* Offset from fp of the place to store the result */ func_vc = 12; /* Offset from fp of the place to store the result */
@ -1336,8 +1361,8 @@ void gfunc_prolog(CType *func_type)
size = (size + 3) >> 2; size = (size + 3) >> 2;
align = (align + 3) & ~3; align = (align + 3) & ~3;
#ifdef TCC_ARM_EABI #ifdef TCC_ARM_EABI
if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t) if (float_abi == ARM_HARD_FLOAT && !func_var &&
|| is_hgen_float_aggr(&sym->type))) { (is_float(sym->type.t) || is_hgen_float_aggr(&sym->type))) {
int fpn = assign_vfpreg(&avregs, align, size << 2); int fpn = assign_vfpreg(&avregs, align, size << 2);
if (fpn >= 0) if (fpn >= 0)
addr = fpn * 4; addr = fpn * 4;
@ -1403,7 +1428,8 @@ void gfunc_epilog(void)
o(0xE04BD00C); /* sub sp,fp,ip */ o(0xE04BD00C); /* sub sp,fp,ip */
o(0xE1A0F00E); /* mov pc,lr */ o(0xE1A0F00E); /* mov pc,lr */
o(diff); o(diff);
*(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1); *(uint32_t*)(cur_text_section->data + func_sub_sp_offset) =
0xE1000000 | encbranch(func_sub_sp_offset, addr, 1);
} }
} }
} }
@ -1559,7 +1585,8 @@ void gen_opi(int op)
c = vtop[-1].r; c = vtop[-1].r;
vtop[-1].r = get_reg_ex(RC_INT, regmask(c)); vtop[-1].r = get_reg_ex(RC_INT, regmask(c));
vtop--; vtop--;
o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r)); o(0xE0800090 | (r << 16) | (intr(vtop->r) << 12) | (intr(c) << 8) |
intr(vtop[1].r));
return; return;
default: default:
opc = 0x15; opc = 0x15;
@ -1591,7 +1618,8 @@ void gen_opi(int op)
} }
} }
fr = intr(gv(RC_INT)); fr = intr(gv(RC_INT));
r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r))); r = intr(vtop[-1].r =
get_reg_ex(RC_INT, two2mask(vtop->r, vtop[-1].r)));
o(opc | (r << 12) | fr); o(opc | (r << 12) | fr);
done: done:
vtop--; vtop--;
@ -1615,7 +1643,8 @@ done:
o(opc | (c << 7) | (fr << 12)); o(opc | (c << 7) | (fr << 12));
} else { } else {
fr = intr(gv(RC_INT)); fr = intr(gv(RC_INT));
c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r))); c = intr(vtop[-1].r =
get_reg_ex(RC_INT, two2mask(vtop->r, vtop[-1].r)));
o(opc | (c << 12) | (fr << 8) | 0x10); o(opc | (c << 12) | (fr << 8) | 0x10);
} }
vtop--; vtop--;
@ -1699,7 +1728,8 @@ void gen_opf(int op)
x |= 0x80; /* fcmpX -> fcmpeX */ x |= 0x80; /* fcmpX -> fcmpeX */
if (is_zero(0)) { if (is_zero(0)) {
vtop--; vtop--;
o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */ o(x | 0x10000 |
(vfpr(gv(RC_FLOAT)) << 12)); /* fcmp(e)X -> fcmp(e)zX */
} else { } else {
x |= vfpr(gv(RC_FLOAT)); x |= vfpr(gv(RC_FLOAT));
vswap(); vswap();
@ -1794,8 +1824,7 @@ void gen_opf(int op)
else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
x |= 0x80000; x |= 0x80000;
#endif #endif
switch(op) switch (op) {
{
case '+': case '+':
if (!c2) { if (!c2) {
vswap(); vswap();
@ -1883,7 +1912,8 @@ void gen_opf(int op)
op = TOK_Nset; op = TOK_Nset;
break; break;
case TOK_LE: case TOK_LE:
op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */ op = TOK_ULE; /* correct in unordered case only if AC bit in
FPSR set */
break; break;
case TOK_EQ: case TOK_EQ:
case TOK_NE: case TOK_NE:
@ -1963,7 +1993,8 @@ ST_FUNC void gen_cvt_itof1(int t)
if ((t & VT_BTYPE) != VT_FLOAT) if ((t & VT_BTYPE) != VT_FLOAT)
dsize = 0x80; /* flts -> fltd */ dsize = 0x80; /* flts -> fltd */
o(0xEE000110 | dsize | (r2 << 16) | (r << 12)); /* flts */ o(0xEE000110 | dsize | (r2 << 16) | (r << 12)); /* flts */
if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) { if ((vtop->type.t & (VT_UNSIGNED | VT_BTYPE)) ==
(VT_UNSIGNED | VT_INT)) {
uint32_t off = 0; uint32_t off = 0;
o(0xE3500000 | (r << 12)); /* cmp */ o(0xE3500000 | (r << 12)); /* cmp */
r = fpr(get_reg(RC_FLOAT)); r = fpr(get_reg(RC_FLOAT));
@ -2001,7 +2032,8 @@ ST_FUNC void gen_cvt_itof1(int t)
func = TOK___floatdixf; func = TOK___floatdixf;
} else if ((t & VT_BTYPE) == VT_DOUBLE) { } else if ((t & VT_BTYPE) == VT_DOUBLE) {
#else #else
} else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) { } else if ((t & VT_BTYPE) == VT_DOUBLE ||
(t & VT_BTYPE) == VT_LDOUBLE) {
#endif #endif
func_type = &func_double_type; func_type = &func_double_type;
if (vtop->type.t & VT_UNSIGNED) if (vtop->type.t & VT_UNSIGNED)
@ -2085,12 +2117,14 @@ void gen_cvt_ftoi(int t)
void gen_cvt_ftof(int t) void gen_cvt_ftof(int t)
{ {
#ifdef TCC_ARM_VFP #ifdef TCC_ARM_VFP
if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) { if (((vtop->type.t & VT_BTYPE) == VT_FLOAT) !=
((t & VT_BTYPE) == VT_FLOAT)) {
uint32_t r = vfpr(gv(RC_FLOAT)); uint32_t r = vfpr(gv(RC_FLOAT));
o(0xEEB70AC0 | (r << 12) | r | T2CPR(vtop->type.t)); o(0xEEB70AC0 | (r << 12) | r | T2CPR(vtop->type.t));
} }
#else #else
/* all we have to do on i386 and FPA ARM is to put the float in a register */ /* all we have to do on i386 and FPA ARM is to put the float in a register
*/
gv(RC_FLOAT); gv(RC_FLOAT);
#endif #endif
} }
@ -2102,18 +2136,23 @@ void ggoto(void)
vtop--; vtop--;
} }
/* Save the stack pointer onto the stack and return the location of its address */ /* Save the stack pointer onto the stack and return the location of its address
ST_FUNC void gen_vla_sp_save(int addr) { */
ST_FUNC void gen_vla_sp_save(int addr)
{
tcc_error("variable length arrays unsupported for this target"); tcc_error("variable length arrays unsupported for this target");
} }
/* Restore the SP from a location on the stack */ /* Restore the SP from a location on the stack */
ST_FUNC void gen_vla_sp_restore(int addr) { ST_FUNC void gen_vla_sp_restore(int addr)
{
tcc_error("variable length arrays unsupported for this target"); tcc_error("variable length arrays unsupported for this target");
} }
/* Subtract from the stack pointer, and push the resulting value onto the stack */ /* Subtract from the stack pointer, and push the resulting value onto the stack
ST_FUNC void gen_vla_alloc(CType *type, int align) { */
ST_FUNC void gen_vla_alloc(CType* type, int align)
{
tcc_error("variable length arrays unsupported for this target"); tcc_error("variable length arrays unsupported for this target");
} }

View file

@ -102,14 +102,14 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
o_filehdr.magic = 0x0108; /* see magic.h */ o_filehdr.magic = 0x0108; /* see magic.h */
o_filehdr.vstamp = 0x0190; /* version stamp */ o_filehdr.vstamp = 0x0190; /* version stamp */
o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */ o_filehdr.tsize =
stext->data_offset; /* text size in bytes, padded to FW bdry */
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */ o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */ o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */ o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */ o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */ o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
// create all the section headers // create all the section headers
file_pointer = FILHSZ + sizeof(AOUTHDR); file_pointer = FILHSZ + sizeof(AOUTHDR);
@ -124,7 +124,9 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
NSectionsToOutput++; NSectionsToOutput++;
if (CoffTextSectionNo == -1 && tcc_sect == stext) if (CoffTextSectionNo == -1 && tcc_sect == stext)
CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is CoffTextSectionNo = NSectionsToOutput; // rem which coff sect
// number the .text sect
// is
strcpy(coff_sec->s_name, tcc_sect->name); /* section name */ strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
@ -148,14 +150,14 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
// now loop through and determine file pointer locations // now loop through and determine file pointer locations
// for the raw data // for the raw data
for (i = 1; i < s1->nb_sections; i++) { for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i]; coff_sec = &section_header[i];
tcc_sect = s1->sections[i]; tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) { if (OutputTheSection(tcc_sect)) {
// put raw data // put raw data
coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */ coff_sec->s_scnptr =
file_pointer; /* file ptr to raw data for section */
file_pointer += coff_sec->s_size; file_pointer += coff_sec->s_size;
} }
} }
@ -192,7 +194,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
// also find association between source file name and function // also find association between source file name and function
// so we can sort the symbol table // so we can sort the symbol table
Stab_Sym* sym, *sym_end; Stab_Sym* sym, *sym_end;
char func_name[MAX_FUNC_NAME_LENGTH], char func_name[MAX_FUNC_NAME_LENGTH],
last_func_name[MAX_FUNC_NAME_LENGTH]; last_func_name[MAX_FUNC_NAME_LENGTH];
@ -203,7 +204,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */ coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
func_name[0] = '\0'; func_name[0] = '\0';
func_addr = 0; func_addr = 0;
incl_index = 0; incl_index = 0;
@ -212,8 +212,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
last_line_num = 1; last_line_num = 1;
sym = (Stab_Sym*)stab_section->data + 1; sym = (Stab_Sym*)stab_section->data + 1;
sym_end = sym_end =
(Stab_Sym *) (stab_section->data + (Stab_Sym*)(stab_section->data + stab_section->data_offset);
stab_section->data_offset);
nFuncs = 0; nFuncs = 0;
while (sym < sym_end) { while (sym < sym_end) {
@ -231,8 +230,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
func_addr = 0; func_addr = 0;
EndAddress[nFuncs] = pc; EndAddress[nFuncs] = pc;
FuncEntries[nFuncs] = FuncEntries[nFuncs] =
(file_pointer - (file_pointer - LineNoFilePtr[nFuncs]) / LINESZ - 1;
LineNoFilePtr[nFuncs]) / LINESZ - 1;
LastLineNo[nFuncs++] = last_line_num + 1; LastLineNo[nFuncs++] = last_line_num + 1;
} else { } else {
// beginning of function // beginning of function
@ -241,9 +239,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
coff_sec->s_nlnno++; coff_sec->s_nlnno++;
file_pointer += LINESZ; file_pointer += LINESZ;
str = str = (const char*)stabstr_section->data + sym->n_strx;
(const char *) stabstr_section->data +
sym->n_strx;
p = strchr(str, ':'); p = strchr(str, ':');
if (!p) { if (!p) {
@ -281,8 +277,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
break; break;
/* include files */ /* include files */
case N_BINCL: case N_BINCL:
str = str = (const char*)stabstr_section->data + sym->n_strx;
(const char *) stabstr_section->data + sym->n_strx;
add_incl: add_incl:
if (incl_index < INCLUDE_STACK_SIZE) { if (incl_index < INCLUDE_STACK_SIZE) {
incl_files[incl_index++] = str; incl_files[incl_index++] = str;
@ -296,9 +291,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
if (sym->n_strx == 0) { if (sym->n_strx == 0) {
incl_index = 0; /* end of translation unit */ incl_index = 0; /* end of translation unit */
} else { } else {
str = str = (const char*)stabstr_section->data + sym->n_strx;
(const char *) stabstr_section->data +
sym->n_strx;
/* do not add path */ /* do not add path */
len = strlen(str); len = strlen(str);
if (len > 0 && str[len - 1] != '/') if (len > 0 && str[len - 1] != '/')
@ -309,7 +302,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
sym++; sym++;
} }
} }
} }
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */ file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
@ -323,7 +315,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
// OK now we are all set to write the file // OK now we are all set to write the file
fwrite(&file_hdr, FILHSZ, 1, f); fwrite(&file_hdr, FILHSZ, 1, f);
fwrite(&o_filehdr, sizeof(o_filehdr), 1, f); fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
@ -361,7 +352,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
} }
} }
// group the symbols in order of filename, func1, func2, etc // group the symbols in order of filename, func1, func2, etc
// finally global symbols // finally global symbols
@ -377,7 +367,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
if (s1->do_debug && tcc_sect == stext) { if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data // count how many line nos data
Stab_Sym* sym, *sym_end; Stab_Sym* sym, *sym_end;
char func_name[128], last_func_name[128]; char func_name[128], last_func_name[128];
unsigned long func_addr, last_pc, pc; unsigned long func_addr, last_pc, pc;
@ -395,8 +384,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
last_line_num = 1; last_line_num = 1;
sym = (Stab_Sym*)stab_section->data + 1; sym = (Stab_Sym*)stab_section->data + 1;
sym_end = sym_end =
(Stab_Sym *) (stab_section->data + (Stab_Sym*)(stab_section->data + stab_section->data_offset);
stab_section->data_offset);
while (sym < sym_end) { while (sym < sym_end) {
switch (sym->n_type) { switch (sym->n_type) {
@ -415,10 +403,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
} else { } else {
// beginning of function // beginning of function
str = str = (const char*)stabstr_section->data + sym->n_strx;
(const char *) stabstr_section->data +
sym->n_strx;
p = strchr(str, ':'); p = strchr(str, ':');
if (!p) { if (!p) {
@ -448,7 +433,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
case N_SLINE: case N_SLINE:
pc = sym->n_value + func_addr; pc = sym->n_value + func_addr;
/* XXX: slow! */ /* XXX: slow! */
strcpy(last_func_name, func_name); strcpy(last_func_name, func_name);
@ -471,8 +455,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
/* include files */ /* include files */
case N_BINCL: case N_BINCL:
str = str = (const char*)stabstr_section->data + sym->n_strx;
(const char *) stabstr_section->data + sym->n_strx;
add_incl2: add_incl2:
if (incl_index < INCLUDE_STACK_SIZE) { if (incl_index < INCLUDE_STACK_SIZE) {
incl_files[incl_index++] = str; incl_files[incl_index++] = str;
@ -486,9 +469,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
if (sym->n_strx == 0) { if (sym->n_strx == 0) {
incl_index = 0; /* end of translation unit */ incl_index = 0; /* end of translation unit */
} else { } else {
str = str = (const char*)stabstr_section->data + sym->n_strx;
(const char *) stabstr_section->data +
sym->n_strx;
/* do not add path */ /* do not add path */
len = strlen(str); len = strlen(str);
if (len > 0 && str[len - 1] != '/') if (len > 0 && str[len - 1] != '/')
@ -520,7 +501,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
p = (Elf32_Sym*)symtab_section->data; p = (Elf32_Sym*)symtab_section->data;
for (i = 0; i < nb_syms; i++) { for (i = 0; i < nb_syms; i++) {
name = symtab_section->link->data + p->st_name; name = symtab_section->link->data + p->st_name;
@ -536,8 +516,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
tcc_error("String table too large"); tcc_error("String table too large");
csym._n._n_n._n_zeroes = 0; csym._n._n_n._n_zeroes = 0;
csym._n._n_n._n_offset = csym._n._n_n._n_offset = pCoff_str_table - Coff_str_table + 4;
pCoff_str_table - Coff_str_table + 4;
strcpy(pCoff_str_table, name); strcpy(pCoff_str_table, name);
pCoff_str_table += strlen(name) + 1; // skip over null pCoff_str_table += strlen(name) + 1; // skip over null
@ -648,7 +627,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
csym.n_sclass = C_LABEL; csym.n_sclass = C_LABEL;
} }
csym.n_value = p->st_value; csym.n_value = p->st_value;
csym.n_scnum = 2; csym.n_scnum = 2;
csym.n_numaux = 1; csym.n_numaux = 1;
@ -662,7 +640,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
fwrite(&auxfunc, 18, 1, f); fwrite(&auxfunc, 18, 1, f);
n++; n++;
n++; n++;
} }
p++; p++;
@ -685,8 +662,6 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
return 0; return 0;
} }
// group the symbols in order of filename, func1, func2, etc // group the symbols in order of filename, func1, func2, etc
// finally global symbols // finally global symbols
@ -700,7 +675,6 @@ void SortSymbolTable(void)
p = (Elf32_Sym*)symtab_section->data; p = (Elf32_Sym*)symtab_section->data;
// find a file symbol, copy it over // find a file symbol, copy it over
// then scan the whole symbol list and copy any function // then scan the whole symbol list and copy any function
// symbols that match the file association // symbols that match the file association
@ -719,8 +693,7 @@ void SortSymbolTable(void)
if (p2->st_info == 0x12) { if (p2->st_info == 0x12) {
// this is a func symbol // this is a func symbol
name2 = name2 = (char*)symtab_section->link->data + p2->st_name;
(char *) symtab_section->link->data + p2->st_name;
// find the function data index // find the function data index
@ -730,7 +703,8 @@ void SortSymbolTable(void)
} }
if (k >= nFuncs) { if (k >= nFuncs) {
tcc_error("debug (sort) info can't find function: %s", name2); tcc_error("debug (sort) info can't find function: %s",
name2);
} }
if (strcmp(AssociatedFile[k], name) == 0) { if (strcmp(AssociatedFile[k], name) == 0) {
@ -769,7 +743,6 @@ void SortSymbolTable(void)
tcc_free(NewTable); tcc_free(NewTable);
} }
int FindCoffSymbolIndex(const char* func_name) int FindCoffSymbolIndex(const char* func_name)
{ {
int i, n = 0; int i, n = 0;
@ -889,7 +862,6 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
if (fread(&str_size, sizeof(int), 1, f) != 1) if (fread(&str_size, sizeof(int), 1, f) != 1)
tcc_error("error reading .out file for input"); tcc_error("error reading .out file for input");
Coff_str_table = (char*)tcc_malloc(str_size); Coff_str_table = (char*)tcc_malloc(str_size);
if (fread(Coff_str_table, str_size - 4, 1, f) != 1) if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
@ -923,8 +895,12 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
// if (strcmp("_DAC_Buffer",name)==0) // tktk // if (strcmp("_DAC_Buffer",name)==0) // tktk
// name[0]=0; // name[0]=0;
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 if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) ||
(csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure ((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
(csym.n_type == 0x18 &&
csym.n_sclass == 0x2) || // pointer to structure
(csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
(csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
{ {