[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] Re: Please comment this patch, if you have the time.
From: |
Jakob Eriksson |
Subject: |
[Tinycc-devel] Re: Please comment this patch, if you have the time. |
Date: |
Sun, 30 Sep 2007 21:13:37 +0200 |
User-agent: |
Thunderbird 1.5.0.13 (X11/20070824) |
Rob Landley wrote:
>
> Getting back to "that's a horrible name for this proposed function"...
>
> Let's see, according to http://sandpile.org/ia32 the opcode 0x85 is "TEST
> Eb,Gb" and 0x0f is the prefix to indicate a two byte opcode follows. At a
> guess the function name indicates an x86 "test and jump".
>
> Except that the function _contents_ start by sticking 0x1a at the start of
> it,
> which is "SBB Gb, Eb" and I have no _IDEA_ what that means, but google
> probably will... http://en.wikipedia.org/wiki/X86_assembly_language
> says "subtraction with borrow". Ok...
>
> Anybody else understand what this is doing?
>
By the way, this is (almost) the patch Rob was referring to.
regards,
Jakob
diff -r c8a874736ed2 arm-gen.c
--- a/arm-gen.c Thu Sep 27 19:29:20 2007 -0500
+++ b/arm-gen.c Thu Sep 27 08:44:17 2007 +0200
@@ -1695,6 +1695,34 @@ void ggoto(void)
vtop--;
}
+int gen_jnz(int ind)
+{
+ o(0x1A000000 | encbranch(ind, 0, 1));
+
+ return ind;
+}
+
+const int double_align =
+#ifdef TCC_ARM_EABI
+ 8
+#else
+ 4
+#endif
+ ;
+
+int tcc_define_symbols_platform(TCCState *s)
+{
+ tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
+ tcc_define_symbol(s, "__arm_elf__", NULL);
+ tcc_define_symbol(s, "__arm_elf", NULL);
+ tcc_define_symbol(s, "arm_elf", NULL);
+ tcc_define_symbol(s, "__arm__", NULL);
+ tcc_define_symbol(s, "__arm", NULL);
+ tcc_define_symbol(s, "arm", NULL);
+ tcc_define_symbol(s, "__APCS_32__", NULL);
+}
+
+
/* end of ARM code generator */
/*************************************************************/
diff -r c8a874736ed2 c67-gen.c
--- a/c67-gen.c Thu Sep 27 19:29:20 2007 -0500
+++ b/c67-gen.c Thu Sep 27 08:44:35 2007 +0200
@@ -2544,5 +2544,13 @@ void ggoto(void)
vtop--;
}
-/* end of X86 code generator */
+int gen_jnz(int ind)
+{
+ error ("not implemented");
+
+ return 0;
+}
+
+
+/* end of C67 code generator */
/*************************************************************/
diff -r c8a874736ed2 i386/i386-asm.c
--- a/i386/i386-asm.c Thu Sep 27 19:29:20 2007 -0500
+++ b/i386/i386-asm.c Wed Sep 26 22:27:40 2007 +0200
@@ -1207,3 +1207,9 @@ static void asm_clobber(uint8_t *clobber
}
clobber_regs[reg] = 1;
}
+
+int gen_jnz(int ind)
+{
+ return psym(0x850f, 0);
+}
+
diff -r c8a874736ed2 i386/i386-gen.c
--- a/i386/i386-gen.c Thu Sep 27 19:29:20 2007 -0500
+++ b/i386/i386-gen.c Fri Sep 28 18:28:51 2007 +0200
@@ -1022,6 +1022,21 @@ void gen_bounded_ptr_deref(void)
put_extern_sym(sym, NULL, 0, 0);
rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
}
+
+void inline pop_fp_r (int r)
+{
+ if (TREG_ST0 == r) {
+ o(0xd9dd); /* fstp %st(1) */
+ }
+}
+
+const int double_align = 4;
+
+int tcc_define_symbols_platform(TCCState *s)
+{
+ tcc_define_symbol(s, "__i386__", NULL);
+}
+
#endif
/* end of X86 code generator */
diff -r c8a874736ed2 tcc.c
--- a/tcc.c Thu Sep 27 19:29:20 2007 -0500
+++ b/tcc.c Fri Sep 28 22:59:12 2007 +0200
@@ -3754,12 +3754,9 @@ void save_reg(int r)
sv.r = VT_LOCAL | VT_LVAL;
sv.c.ul = loc;
store(r, &sv);
-#ifdef TCC_TARGET_I386
- /* x86 specific: need to pop fp register ST0 if saved */
- if (r == TREG_ST0) {
- o(0xd9dd); /* fstp %st(1) */
- }
-#endif
+
+ pop_fp_r (r);
+
/* special long long case */
if ((type->t & VT_BTYPE) == VT_LLONG) {
sv.c.ul += 4;
@@ -4195,12 +4192,7 @@ void vpop(void)
{
int v;
v = vtop->r & VT_VALMASK;
-#ifdef TCC_TARGET_I386
- /* for x86, we need to pop the FP stack */
- if (v == TREG_ST0) {
- o(0xd9dd); /* fstp %st(1) */
- } else
-#endif
+ pop_fp_r (v);
if (v == VT_JMP || v == VT_JMPI) {
/* need to put correct jump if && or || without test */
gsym(vtop->c.ul);
@@ -4447,16 +4439,7 @@ void gen_opl(int op)
if (a == 0) {
b = gtst(0, 0);
} else {
-#if defined(TCC_TARGET_I386)
- b = psym(0x850f, 0);
-#elif defined(TCC_TARGET_ARM)
- b = ind;
- o(0x1A000000 | encbranch(ind, 0, 1));
-#elif defined(TCC_TARGET_C67)
- error("not implemented");
-#else
-#error not supported
-#endif
+ b = gen_jnz (ind);
}
}
/* compare low. Always unsigned */
@@ -4588,9 +4571,12 @@ void gen_opic(int op)
vtop->c.i += fc;
} else {
general_case:
- /* call low level op generator */
- if (cur_text_section) gen_opi(op);
- else vtop--;
+ if (!nocode_wanted) {
+ /* call low level op generator */
+ gen_opi(op);
+ } else {
+ vtop--;
+ }
}
}
}
@@ -4651,8 +4637,11 @@ void gen_opif(int op)
vtop--;
} else {
general_case:
- if (cur_text_section) gen_opf(op);
- else vtop--;
+ if (!nocode_wanted) {
+ gen_opf(op);
+ } else {
+ vtop--;
+ }
}
}
@@ -4954,7 +4943,7 @@ static void gen_cast(CType *type)
dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
- if (sbt != dbt && cur_text_section) {
+ if (sbt != dbt && !nocode_wanted) {
sf = is_float(sbt);
df = is_float(dbt);
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
@@ -5133,17 +5122,7 @@ static int type_size(CType *type, int *a
*a = LDOUBLE_ALIGN;
return LDOUBLE_SIZE;
} else if (bt == VT_DOUBLE || bt == VT_LLONG) {
-#ifdef TCC_TARGET_I386
- *a = 4;
-#elif defined(TCC_TARGET_ARM)
-#ifdef TCC_ARM_EABI
- *a = 8;
-#else
- *a = 4;
-#endif
-#else
- *a = 8;
-#endif
+ *a = double_align;
return 8;
} else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
*a = 4;
@@ -5433,7 +5412,7 @@ void vstore(void)
/* if structure, only generate pointer */
/* structure assignment : generate memcpy */
/* XXX: optimize if small size */
- if (cur_text_section) {
+ if (!nocode_wanted) {
size = type_size(&vtop->type, &align);
#ifdef TCC_ARM_EABI
@@ -5505,7 +5484,7 @@ void vstore(void)
vswap();
}
#endif
- if (cur_text_section) {
+ if (!nocode_wanted) {
rc = RC_INT;
if (is_float(ft))
rc = RC_FLOAT;
@@ -6252,7 +6231,7 @@ static void indir(void)
return;
expect("pointer");
}
- if ((vtop->r & VT_LVAL) && cur_text_section)
+ if ((vtop->r & VT_LVAL) && !nocode_wanted)
gv(RC_INT);
vtop->type = *pointed_type(&vtop->type);
/* Arrays and functions are never lvalues */
@@ -6523,16 +6502,15 @@ static void unary(void)
break;
case TOK_builtin_constant_p:
{
- Section *saved_text_section;
- int res;
+ int saved_nocode_wanted, res;
next();
skip('(');
- saved_text_section = cur_text_section;
- cur_text_section = NULL;
+ saved_nocode_wanted = nocode_wanted;
+ nocode_wanted = 1;
gexpr();
res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
vpop();
- cur_text_section = saved_text_section;
+ nocode_wanted = saved_nocode_wanted;
skip(')');
vpushi(res);
}
@@ -6720,8 +6698,11 @@ static void unary(void)
if (sa)
error("too few arguments to function");
skip(')');
- if (cur_text_section) gfunc_call(nb_args);
- else vtop -= (nb_args + 1);
+ if (!nocode_wanted) {
+ gfunc_call(nb_args);
+ } else {
+ vtop -= (nb_args + 1);
+ }
/* return value */
vsetc(&ret.type, ret.r, &ret.c);
vtop->r2 = ret.r2;
@@ -7055,26 +7036,28 @@ static void gexpr(void)
/* parse an expression and return its type without any side effect. */
static void expr_type(CType *type)
{
- Section *saved_text_section = cur_text_section;
-
- cur_text_section = NULL;
+ int saved_nocode_wanted;
+
+ saved_nocode_wanted = nocode_wanted;
+ nocode_wanted = 1;
gexpr();
*type = vtop->type;
vpop();
- cur_text_section = saved_text_section;
+ nocode_wanted = saved_nocode_wanted;
}
/* parse a unary expression and return its type without any side
effect. */
static void unary_type(CType *type)
{
- Section *saved_text_section = cur_text_section;
-
- cur_text_section = NULL;
+ int a;
+
+ a = nocode_wanted;
+ nocode_wanted = 1;
unary();
*type = vtop->type;
vpop();
- cur_text_section = saved_text_section;
+ nocode_wanted = a;
}
/* parse a constant expression and return value in vtop. */
@@ -7605,7 +7588,7 @@ static void init_putv(CType *type, Secti
expr_eq();
break;
}
-
+
dtype = *type;
dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
@@ -8410,6 +8393,8 @@ static void decl(int l)
extern */
external_sym(v, &type, r);
} else {
+ int saved_nocode_wanted = nocode_wanted;
+
type.t |= (btype.t & VT_STATIC); // Retain "static".
if (type.t & VT_STATIC)
r |= VT_CONST;
@@ -8417,8 +8402,10 @@ static void decl(int l)
r |= l;
if (has_init)
next();
+ nocode_wanted = !cur_text_section;
decl_initializer_alloc(&type, &ad, r,
has_init, v, l);
+ nocode_wanted = saved_nocode_wanted;
}
}
if (tok != ',') {
@@ -8441,7 +8428,8 @@ static void preprocess_init(TCCState *s1
s1->ifdef_stack_ptr = s1->ifdef_stack;
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
- vtop = vstack;
+ /* XXX: not ANSI compliant: bound checking says error */
+ vtop = vstack - 1;
s1->pack_stack[0] = 0;
s1->pack_stack_ptr = s1->pack_stack;
}
@@ -8826,19 +8814,7 @@ TCCState *tcc_new(void)
/* standard defines */
tcc_define_symbol(s, "__STDC__", NULL);
tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
-#if defined(TCC_TARGET_I386)
- tcc_define_symbol(s, "__i386__", NULL);
-#endif
-#if defined(TCC_TARGET_ARM)
- tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
- tcc_define_symbol(s, "__arm_elf__", NULL);
- tcc_define_symbol(s, "__arm_elf", NULL);
- tcc_define_symbol(s, "arm_elf", NULL);
- tcc_define_symbol(s, "__arm__", NULL);
- tcc_define_symbol(s, "__arm", NULL);
- tcc_define_symbol(s, "arm", NULL);
- tcc_define_symbol(s, "__APCS_32__", NULL);
-#endif
+ tcc_define_symbols_platform(s);
#if defined(linux)
tcc_define_symbol(s, "__linux__", NULL);
tcc_define_symbol(s, "linux", NULL);