diff options
| author | Michael Matz <matz@suse.de> | 2016-06-29 15:57:32 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:47:07 +0100 |
| commit | 8e4da42384164d6eb862665d907b3b1138da2f94 (patch) | |
| tree | fe7ac034c9839d95f9c2580f6e6d2b54b4743cdd /i386-asm.c | |
| parent | c82e52d55bd31eea943c616ad780f27e5ab9dc7a (diff) | |
| download | tinycc-8e4da42384164d6eb862665d907b3b1138da2f94.tar.gz tinycc-8e4da42384164d6eb862665d907b3b1138da2f94.tar.bz2 | |
Accept more asm expressions
In particular subtracting a defined symbol from current section
makes the value PC relative, and .org accepts symbolic expressions
as well, if the symbol is from the current section.
Diffstat (limited to 'i386-asm.c')
| -rw-r--r-- | i386-asm.c | 14 |
1 files changed, 9 insertions, 5 deletions
@@ -356,8 +356,7 @@ static void parse_operand(TCCState *s1, Operand *op) next(); asm_expr(s1, &e); op->type = OP_IM32; - op->e.v = e.v; - op->e.sym = e.sym; + op->e = e; if (!op->e.sym) { if (op->e.v == (uint8_t)op->e.v) op->type |= OP_IM8; @@ -378,8 +377,7 @@ static void parse_operand(TCCState *s1, Operand *op) op->shift = 0; if (tok != '(') { asm_expr(s1, &e); - op->e.v = e.v; - op->e.sym = e.sym; + op->e = e; } else { next(); if (tok == '%') { @@ -395,6 +393,7 @@ static void parse_operand(TCCState *s1, Operand *op) op->e.v = e.v; op->e.sym = e.sym; } + op->e.pcrel = 0; } if (tok == '(') { int type = 0; @@ -425,7 +424,12 @@ static void parse_operand(TCCState *s1, Operand *op) /* XXX: unify with C code output ? */ ST_FUNC void gen_expr32(ExprValue *pe) { - gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); + if (pe->pcrel) + /* If PC-relative, always set VT_SYM, even without symbol, + so as to force a relocation to be emitted. */ + gen_addrpc32(VT_SYM, pe->sym, pe->v); + else + gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); } #ifdef TCC_TARGET_X86_64 |
