From 8e4da42384164d6eb862665d907b3b1138da2f94 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Wed, 29 Jun 2016 15:57:32 +0200 Subject: 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. --- i386-asm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'i386-asm.c') diff --git a/i386-asm.c b/i386-asm.c index e7449bf..064b8aa 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -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 -- cgit v1.3.1