* "expr(,1)" (which is definitely an effective address).
*/
unsigned int strong:1;
+
+ /** 1 if effective address is forced PC-relative. */
+ unsigned int pc_rel:1;
+
+ /** 1 if effective address is forced non-PC-relative. */
+ unsigned int not_pc_rel:1;
};
/** An instruction operand (opaque type). */
ea->nosplit = 0;
ea->strong = 0;
ea->segreg = 0;
+ ea->pc_rel = 0;
+ ea->not_pc_rel = 0;
return ea;
}
EXTRA_DIST += modules/arch/x86/tests/rep.hex
EXTRA_DIST += modules/arch/x86/tests/ret.asm
EXTRA_DIST += modules/arch/x86/tests/ret.hex
+EXTRA_DIST += modules/arch/x86/tests/riprel1.asm
+EXTRA_DIST += modules/arch/x86/tests/riprel1.hex
+EXTRA_DIST += modules/arch/x86/tests/riprel2.asm
+EXTRA_DIST += modules/arch/x86/tests/riprel2.errwarn
+EXTRA_DIST += modules/arch/x86/tests/riprel2.hex
EXTRA_DIST += modules/arch/x86/tests/segmov.asm
EXTRA_DIST += modules/arch/x86/tests/segmov.hex
EXTRA_DIST += modules/arch/x86/tests/shift.asm
--- /dev/null
+bits 64
+val:
+default abs
+
+mov rax, val ; 32-bit imm
+mov rax, dword val ; 32-bit imm
+mov rax, qword val ; 64-bit imm
+
+mov rbx, val ; 32-bit imm
+mov rbx, dword val ; 32-bit imm
+mov rbx, qword val ; 64-bit imm
+
+mov rax, [val] ; 48 8b ... (32-bit disp)
+mov rax, [dword val] ; 48 8b ... (32-bit disp)
+mov rax, [qword val] ; 48 a1 ... (64-bit disp)
+a32 mov rax, [val] ; 67 48 a1 ... (32-bit disp)
+a32 mov rax, [dword val] ; 67 48 a1 ... (32-bit disp)
+a32 mov rax, [qword val] ; 67 48 a1 ... (32-bit disp)
+ ; [this one is debatable on correctness,
+ ; I chose in yasm to make a32 override]
+a64 mov rax, [val] ; 48 8b ... (32-bit disp)
+a64 mov rax, [dword val] ; 48 8b ... (32-bit disp)
+a64 mov rax, [qword val] ; 48 a1 ... (64-bit disp)
+
+mov rbx, [val] ; 48 8b ... (32-bit disp)
+mov rbx, [dword val] ; 48 8b ... (32-bit disp)
+;mov rbx, [qword val] ; illegal (can't have 64-bit disp)
+a32 mov rbx, [val] ; 67 48 8b ... (32-bit disp)
+a32 mov rbx, [dword val] ; 67 48 8b ... (32-bit disp)
+;a32 mov rbx, [qword val] ; illegal (can't have 64-bit disp)
+a64 mov rbx, [val] ; 48 8b ... (32-bit disp)
+a64 mov rbx, [dword val] ; 48 8b ... (32-bit disp)
+;a64 mov rbx, [qword val] ; illegal (can't have 64-bit disp)
+
+default rel
+
+mov rax, val ; 32-bit imm
+mov rax, dword val ; 32-bit imm
+mov rax, qword val ; 64-bit imm
+
+mov rbx, val ; 32-bit imm
+mov rbx, dword val ; 32-bit imm
+mov rbx, qword val ; 64-bit imm
+
+mov rax, [val] ; 48 8b ... (32-bit disp, RIP-rel)
+mov rax, [dword val] ; 48 8b ... (32-bit disp, RIP-rel)
+mov rax, [qword val] ; 48 a1 ... (64-bit disp, ABS)
+a32 mov rax, [val] ; 67 48 8b ... (32-bit disp, RIP-rel)
+a32 mov rax, [dword val] ; 67 48 8b ... (32-bit disp, RIP-rel)
+a32 mov rax, [qword val] ; 67 48 a1 ... (32-bit disp, ABS)
+ ; [this one is debatable on correctness,
+ ; I chose in yasm to make a32 override]
+a64 mov rax, [val] ; 48 8b ... (32-bit disp, RIP-rel)
+a64 mov rax, [dword val] ; 48 8b ... (32-bit disp, RIP-rel)
+a64 mov rax, [qword val] ; 48 a1 ... (64-bit disp, ABS)
+
+mov rbx, [val] ; 48 8b ... (32-bit disp, RIP-rel)
+mov rbx, [dword val] ; 48 8b ... (32-bit disp, RIP-rel)
+;mov rbx, [qword val] ; illegal (can't have 64-bit disp)
+a32 mov rbx, [val] ; 67 48 8b ... (32-bit disp, RIP-rel)
+a32 mov rbx, [dword val] ; 67 48 8b ... (32-bit disp, RIP-rel)
+;a32 mov rbx, [qword val] ; illegal (can't have 64-bit disp)
+a64 mov rbx, [val] ; 48 8b ... (32-bit disp, RIP-rel)
+a64 mov rbx, [dword val] ; 48 8b ... (32-bit disp, RIP-rel)
+;a64 mov rbx, [qword val] ; illegal (can't have 64-bit disp)
+
--- /dev/null
+48
+c7
+c0
+00
+00
+00
+00
+48
+c7
+c0
+00
+00
+00
+00
+48
+b8
+00
+00
+00
+00
+00
+00
+00
+00
+48
+c7
+c3
+00
+00
+00
+00
+48
+c7
+c3
+00
+00
+00
+00
+48
+bb
+00
+00
+00
+00
+00
+00
+00
+00
+48
+8b
+04
+25
+00
+00
+00
+00
+48
+8b
+04
+25
+00
+00
+00
+00
+48
+a1
+00
+00
+00
+00
+00
+00
+00
+00
+67
+48
+a1
+00
+00
+00
+00
+67
+48
+a1
+00
+00
+00
+00
+67
+48
+a1
+00
+00
+00
+00
+48
+8b
+04
+25
+00
+00
+00
+00
+48
+8b
+04
+25
+00
+00
+00
+00
+48
+a1
+00
+00
+00
+00
+00
+00
+00
+00
+48
+8b
+1c
+25
+00
+00
+00
+00
+48
+8b
+1c
+25
+00
+00
+00
+00
+67
+48
+8b
+1c
+25
+00
+00
+00
+00
+67
+48
+8b
+1c
+25
+00
+00
+00
+00
+48
+8b
+1c
+25
+00
+00
+00
+00
+48
+8b
+1c
+25
+00
+00
+00
+00
+48
+c7
+c0
+00
+00
+00
+00
+48
+c7
+c0
+00
+00
+00
+00
+48
+b8
+00
+00
+00
+00
+00
+00
+00
+00
+48
+c7
+c3
+00
+00
+00
+00
+48
+c7
+c3
+00
+00
+00
+00
+48
+bb
+00
+00
+00
+00
+00
+00
+00
+00
+48
+8b
+05
+1e
+ff
+ff
+ff
+48
+8b
+05
+17
+ff
+ff
+ff
+48
+a1
+00
+00
+00
+00
+00
+00
+00
+00
+67
+48
+8b
+05
+05
+ff
+ff
+ff
+67
+48
+8b
+05
+fd
+fe
+ff
+ff
+67
+48
+a1
+00
+00
+00
+00
+48
+8b
+05
+ef
+fe
+ff
+ff
+48
+8b
+05
+e8
+fe
+ff
+ff
+48
+a1
+00
+00
+00
+00
+00
+00
+00
+00
+48
+8b
+1d
+d7
+fe
+ff
+ff
+48
+8b
+1d
+d0
+fe
+ff
+ff
+67
+48
+8b
+1d
+c8
+fe
+ff
+ff
+67
+48
+8b
+1d
+c0
+fe
+ff
+ff
+48
+8b
+1d
+b9
+fe
+ff
+ff
+48
+8b
+1d
+b2
+fe
+ff
+ff
--- /dev/null
+ bits 64
+
+ default abs ; default abs, except for explicit rel
+
+ mov rax,[foo]
+ mov rax,[qword 123456789abcdef0h]
+ mov rbx,[foo]
+ mov rax,[dword foo]
+ mov rbx,[dword foo]
+ mov rax,[qword foo]
+ mov rax,[rel foo] ; rel
+ mov rbx,[rel foo] ; rel
+ mov rax,[rel dword foo] ; rel
+ ;mov rax,[rel qword foo] ; illegal
+ mov rax,[abs foo]
+ mov rbx,[abs foo]
+ mov rax,[abs dword foo]
+ mov rax,[abs qword foo]
+
+ mov rax,[es:foo]
+ mov rax,[qword es:123456789abcdef0h]
+ mov rbx,[es:foo]
+ mov rax,[dword es:foo]
+ mov rbx,[dword es:foo]
+ mov rax,[qword es:foo]
+ mov rax,[rel es:foo] ; rel
+ mov rbx,[rel es:foo] ; rel
+ mov rax,[rel dword es:foo] ; rel
+ ;mov rax,[rel qword es:foo] ; illegal
+ mov rax,[abs es:foo]
+ mov rbx,[abs es:foo]
+ mov rax,[abs dword es:foo]
+ mov rax,[abs qword es:foo]
+
+ mov rax,[fs:foo]
+ mov rax,[qword fs:123456789abcdef0h]
+ mov rbx,[fs:foo]
+ mov rax,[dword fs:foo]
+ mov rbx,[dword fs:foo]
+ mov rax,[qword fs:foo]
+ mov rax,[rel fs:foo] ; rel
+ mov rbx,[rel fs:foo] ; rel
+ mov rax,[rel dword fs:foo] ; rel
+ ;mov rax,[rel qword fs:foo] ; illegal
+ mov rax,[abs fs:foo]
+ mov rbx,[abs fs:foo]
+ mov rax,[abs dword fs:foo]
+ mov rax,[abs qword fs:foo]
+
+ mov rax,[rbx]
+ mov rax,[rel rbx]
+ mov rax,[abs rbx]
+
+ default rel
+
+ ; all of these are default rel, except for 64-bit displacements
+ mov rax,[foo]
+ mov rax,[qword 123456789abcdef0h] ; abs
+ mov rbx,[foo]
+ mov rax,[dword foo]
+ mov rbx,[dword foo]
+ mov rax,[qword foo] ; abs
+ mov rax,[rel foo]
+ mov rbx,[rel foo]
+ mov rax,[rel dword foo]
+ ;mov rax,[rel qword foo] ; illegal
+ mov rax,[abs foo]
+ mov rbx,[abs foo]
+ mov rax,[abs dword foo]
+ mov rax,[abs qword foo]
+
+ ; all of these are abs due to es:, except for explicit rel
+ mov rax,[es:foo]
+ mov rax,[qword es:123456789abcdef0h]
+ mov rbx,[es:foo]
+ mov rax,[dword es:foo]
+ mov rbx,[dword es:foo]
+ mov rax,[qword es:foo]
+ mov rax,[rel es:foo] ; rel
+ mov rbx,[rel es:foo] ; rel
+ mov rax,[rel dword es:foo] ; rel
+ ;mov rax,[rel qword es:foo] ; illegal
+ mov rax,[abs es:foo]
+ mov rbx,[abs es:foo]
+ mov rax,[abs dword es:foo]
+ mov rax,[abs qword es:foo]
+
+ ; all of these are abs due to fs:, except for explicit rel
+ mov rax,[fs:foo]
+ mov rax,[qword fs:123456789abcdef0h]
+ mov rbx,[fs:foo]
+ mov rax,[dword fs:foo]
+ mov rbx,[dword fs:foo]
+ mov rax,[qword fs:foo]
+ mov rax,[rel fs:foo] ; rel
+ mov rbx,[rel fs:foo] ; rel
+ mov rax,[rel dword fs:foo] ; rel
+ ;mov rax,[rel qword fs:foo] ; illegal
+ mov rax,[abs fs:foo]
+ mov rbx,[abs fs:foo]
+ mov rax,[abs dword fs:foo]
+ mov rax,[abs qword fs:foo]
+
+ mov rax,[rbx]
+ mov rax,[rel rbx]
+ mov rax,[abs rbx]
+
+ section .data
+foo equ $
+
--- /dev/null
+-:20: warning: `es' segment register ignored in 64-bit mode
+-:21: warning: `es' segment register ignored in 64-bit mode
+-:22: warning: `es' segment register ignored in 64-bit mode
+-:23: warning: `es' segment register ignored in 64-bit mode
+-:24: warning: `es' segment register ignored in 64-bit mode
+-:25: warning: `es' segment register ignored in 64-bit mode
+-:26: warning: `es' segment register ignored in 64-bit mode
+-:27: warning: `es' segment register ignored in 64-bit mode
+-:28: warning: `es' segment register ignored in 64-bit mode
+-:30: warning: `es' segment register ignored in 64-bit mode
+-:31: warning: `es' segment register ignored in 64-bit mode
+-:32: warning: `es' segment register ignored in 64-bit mode
+-:33: warning: `es' segment register ignored in 64-bit mode
+-:73: warning: `es' segment register ignored in 64-bit mode
+-:74: warning: `es' segment register ignored in 64-bit mode
+-:75: warning: `es' segment register ignored in 64-bit mode
+-:76: warning: `es' segment register ignored in 64-bit mode
+-:77: warning: `es' segment register ignored in 64-bit mode
+-:78: warning: `es' segment register ignored in 64-bit mode
+-:79: warning: `es' segment register ignored in 64-bit mode
+-:80: warning: `es' segment register ignored in 64-bit mode
+-:81: warning: `es' segment register ignored in 64-bit mode
+-:83: warning: `es' segment register ignored in 64-bit mode
+-:84: warning: `es' segment register ignored in 64-bit mode
+-:85: warning: `es' segment register ignored in 64-bit mode
+-:86: warning: `es' segment register ignored in 64-bit mode
--- /dev/null
+48
+8b
+04
+25
+c4
+02
+00
+00
+48
+a1
+f0
+de
+bc
+9a
+78
+56
+34
+12
+48
+8b
+1c
+25
+c4
+02
+00
+00
+48
+8b
+04
+25
+c4
+02
+00
+00
+48
+8b
+1c
+25
+c4
+02
+00
+00
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+48
+8b
+05
+89
+02
+00
+00
+48
+8b
+1d
+82
+02
+00
+00
+48
+8b
+05
+7b
+02
+00
+00
+48
+8b
+04
+25
+c4
+02
+00
+00
+48
+8b
+1c
+25
+c4
+02
+00
+00
+48
+8b
+04
+25
+c4
+02
+00
+00
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+a1
+f0
+de
+bc
+9a
+78
+56
+34
+12
+26
+48
+8b
+1c
+25
+c4
+02
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+8b
+1c
+25
+c4
+02
+00
+00
+26
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+26
+48
+8b
+05
+17
+02
+00
+00
+26
+48
+8b
+1d
+0f
+02
+00
+00
+26
+48
+8b
+05
+07
+02
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+8b
+1c
+25
+c4
+02
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+a1
+f0
+de
+bc
+9a
+78
+56
+34
+12
+64
+48
+8b
+1c
+25
+c4
+02
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+8b
+1c
+25
+c4
+02
+00
+00
+64
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+64
+48
+8b
+05
+9f
+01
+00
+00
+64
+48
+8b
+1d
+97
+01
+00
+00
+64
+48
+8b
+05
+8f
+01
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+8b
+1c
+25
+c4
+02
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+48
+8b
+03
+48
+8b
+03
+48
+8b
+03
+48
+8b
+05
+59
+01
+00
+00
+48
+a1
+f0
+de
+bc
+9a
+78
+56
+34
+12
+48
+8b
+1d
+48
+01
+00
+00
+48
+8b
+05
+41
+01
+00
+00
+48
+8b
+1d
+3a
+01
+00
+00
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+48
+8b
+05
+29
+01
+00
+00
+48
+8b
+1d
+22
+01
+00
+00
+48
+8b
+05
+1b
+01
+00
+00
+48
+8b
+04
+25
+c4
+02
+00
+00
+48
+8b
+1c
+25
+c4
+02
+00
+00
+48
+8b
+04
+25
+c4
+02
+00
+00
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+a1
+f0
+de
+bc
+9a
+78
+56
+34
+12
+26
+48
+8b
+1c
+25
+c4
+02
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+8b
+1c
+25
+c4
+02
+00
+00
+26
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+26
+48
+8b
+05
+b7
+00
+00
+00
+26
+48
+8b
+1d
+af
+00
+00
+00
+26
+48
+8b
+05
+a7
+00
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+8b
+1c
+25
+c4
+02
+00
+00
+26
+48
+8b
+04
+25
+c4
+02
+00
+00
+26
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+a1
+f0
+de
+bc
+9a
+78
+56
+34
+12
+64
+48
+8b
+1c
+25
+c4
+02
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+8b
+1c
+25
+c4
+02
+00
+00
+64
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+64
+48
+8b
+05
+3f
+00
+00
+00
+64
+48
+8b
+1d
+37
+00
+00
+00
+64
+48
+8b
+05
+2f
+00
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+8b
+1c
+25
+c4
+02
+00
+00
+64
+48
+8b
+04
+25
+c4
+02
+00
+00
+64
+48
+a1
+c4
+02
+00
+00
+00
+00
+00
+00
+48
+8b
+03
+48
+8b
+03
+48
+8b
+03
arch_x86->amd64_machine = amd64_machine;
arch_x86->mode_bits = 0;
arch_x86->force_strict = 0;
+ arch_x86->default_rel = 0;
if (yasm__strcasecmp(parser, "nasm") == 0)
arch_x86->parser = X86_PARSER_NASM;
arch_x86->mode_bits = (unsigned int)val;
else if (yasm__strcasecmp(var, "force_strict") == 0)
arch_x86->force_strict = (unsigned int)val;
- else
+ else if (yasm__strcasecmp(var, "default_rel") == 0) {
+ if (arch_x86->mode_bits != 64)
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("ignoring default rel in non-64-bit mode"));
+ else
+ arch_x86->default_rel = (unsigned int)val;
+ } else
return 1;
return 0;
}
} parser;
unsigned int mode_bits;
unsigned int force_strict;
+ unsigned int default_rel;
} yasm_arch_x86;
/* 0-15 (low 4 bits) used for register number, stored in same data area.
x86_ea->ea.nosplit = 0;
x86_ea->ea.strong = 0;
x86_ea->ea.segreg = 0;
+ x86_ea->ea.pc_rel = 0;
+ x86_ea->ea.not_pc_rel = 0;
x86_ea->modrm = 0;
x86_ea->valid_modrm = 0;
x86_ea->need_modrm = 0;
return 1;
}
+ if (x86_ea->ea.pc_rel && bits != 64) {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("RIP-relative directive ignored in non-64-bit mode"));
+ x86_ea->ea.pc_rel = 0;
+ }
+
reg3264_data.regs = reg3264mult;
reg3264_data.bits = bits;
reg3264_data.addrsize = *addrsize;
* (optional) SIB bytes.
*/
+ /* If we're supposed to be RIP-relative and there's no register
+ * usage, change to RIP-relative.
+ */
+ if (basereg == REG3264_NONE && indexreg == REG3264_NONE &&
+ x86_ea->ea.pc_rel) {
+ basereg = REG64_RIP;
+ yasm_value_set_curpos_rel(&x86_ea->ea.disp, bc, 1);
+ }
+
/* First determine R/M (Mod is later determined from disp size) */
x86_ea->need_modrm = 1; /* we always need ModRM */
if (basereg == REG3264_NONE && indexreg == REG3264_NONE) {
/* Strict forced setting at the time of parsing the instruction */
unsigned int force_strict:1;
+
+ /* Default rel setting at the time of parsing the instruction */
+ unsigned int default_rel:1;
} x86_id_insn;
static void x86_id_insn_destroy(void *contents);
case OPT_MemOffs:
if (op->type != YASM_INSN__OPERAND_MEMORY ||
yasm_expr__contains(op->data.ea->disp.abs,
- YASM_EXPR_REG))
+ YASM_EXPR_REG) ||
+ op->data.ea->pc_rel ||
+ (!op->data.ea->not_pc_rel && id_insn->default_rel &&
+ op->data.ea->disp.size != 64))
mismatch = 1;
break;
case OPT_Imm1:
if (info_ops[i].type == OPT_MemOffs)
/* Special-case for MOV MemOffs instruction */
yasm_x86__ea_set_disponly(insn->x86_ea);
+ else if (id_insn->default_rel &&
+ !op->data.ea->not_pc_rel &&
+ op->data.ea->segreg == 0 &&
+ !yasm_expr__contains(
+ op->data.ea->disp.abs, YASM_EXPR_REG))
+ /* Enable default PC-rel if no regs/segregs */
+ insn->x86_ea->ea.pc_rel = 1;
break;
case YASM_INSN__OPERAND_IMM:
insn->x86_ea =
* short mov instructions if a 32-bit address override is applied in
* 64-bit mode to an EA of just an offset (no registers) and the
* target register is al/ax/eax/rax.
+ *
+ * We don't want to do this if we're in default rel mode.
*/
- if (insn->common.mode_bits == 64 && insn->common.addrsize == 32 &&
+ if (!id_insn->default_rel &&
+ insn->common.mode_bits == 64 &&
+ insn->common.addrsize == 32 &&
(!insn->x86_ea->ea.disp.abs ||
!yasm_expr__contains(insn->x86_ea->ea.disp.abs,
YASM_EXPR_REG))) {
id_insn->suffix = 0;
id_insn->parser = arch_x86->parser;
id_insn->force_strict = arch_x86->force_strict != 0;
+ id_insn->default_rel = arch_x86->default_rel != 0;
*bc = yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
return YASM_ARCH_INSN;
}
id_insn->suffix = pdata->flags;
id_insn->parser = arch_x86->parser;
id_insn->force_strict = arch_x86->force_strict != 0;
+ id_insn->default_rel = arch_x86->default_rel != 0;
*bc = yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
return YASM_ARCH_INSN;
} else {
id_insn->suffix = 0;
id_insn->parser = arch_x86->parser;
id_insn->force_strict = arch_x86->force_strict != 0;
+ id_insn->default_rel = arch_x86->default_rel != 0;
return yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
}
}
get_next_token();
ea = parse_memaddr(parser_nasm);
- if (ea)
+ if (ea) {
yasm_ea_set_segreg(ea, segreg);
+ ea->pc_rel = 0;
+ ea->not_pc_rel = 1;
+ }
return ea;
}
case SIZE_OVERRIDE:
if (ea)
ea->nosplit = 1;
return ea;
+ case REL:
+ get_next_token();
+ ea = parse_memaddr(parser_nasm);
+ if (ea) {
+ ea->pc_rel = 1;
+ ea->not_pc_rel = 0;
+ }
+ return ea;
+ case ABS:
+ get_next_token();
+ ea = parse_memaddr(parser_nasm);
+ if (ea) {
+ ea->pc_rel = 0;
+ ea->not_pc_rel = 1;
+ }
+ return ea;
default:
{
yasm_expr *e = parse_expr(parser_nasm, NORM_EXPR);
objext_valparams, line))
;
else if (yasm__strcasecmp(name, "absolute") == 0) {
- vp = yasm_vps_first(valparams);
- if (parser_nasm->absstart)
- yasm_expr_destroy(parser_nasm->absstart);
- if (parser_nasm->abspos)
- yasm_expr_destroy(parser_nasm->abspos);
- parser_nasm->absstart = yasm_vp_expr(vp, p_object->symtab, line);
- parser_nasm->abspos = yasm_expr_copy(parser_nasm->absstart);
- cursect = NULL;
- parser_nasm->prev_bc = NULL;
+ if (!valparams) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("directive `%s' requires an argument"),
+ "absolute");
+ } else {
+ vp = yasm_vps_first(valparams);
+ if (parser_nasm->absstart)
+ yasm_expr_destroy(parser_nasm->absstart);
+ if (parser_nasm->abspos)
+ yasm_expr_destroy(parser_nasm->abspos);
+ parser_nasm->absstart = yasm_vp_expr(vp, p_object->symtab, line);
+ parser_nasm->abspos = yasm_expr_copy(parser_nasm->absstart);
+ cursect = NULL;
+ parser_nasm->prev_bc = NULL;
+ }
} else if (yasm__strcasecmp(name, "align") == 0) {
/* Really, we shouldn't end up with an align directive in an absolute
* section (as it's supposed to be only used for nop fill), but handle
N_("directive `%s' requires an argument"), "align");
} else
dir_align(p_object, valparams, objext_valparams, line);
+ } else if (yasm__strcasecmp(name, "default") == 0) {
+ if (!valparams)
+ ;
+ else {
+ vp = yasm_vps_first(valparams);
+ while (vp) {
+ const char *id = yasm_vp_id(vp);
+ if (id) {
+ if (yasm__strcasecmp(id, "rel") == 0)
+ yasm_arch_set_var(p_object->arch, "default_rel", 1);
+ else if (yasm__strcasecmp(id, "abs") == 0)
+ yasm_arch_set_var(p_object->arch, "default_rel", 0);
+ else
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("unrecognized default `%s'"), id);
+ } else
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("unrecognized default value"));
+ vp = yasm_vps_next(vp);
+ }
+ }
} else
yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive `%s'"),
name);
TIMES,
SEG,
WRT,
+ ABS,
+ REL,
NOSPLIT,
STRICT,
INSN,
'seg' { RETURN(SEG); }
'wrt' { RETURN(WRT); }
+ 'abs' { RETURN(ABS); }
+ 'rel' { RETURN(REL); }
+
'nosplit' { RETURN(NOSPLIT); }
'strict' { RETURN(STRICT); }
[cpu %1]
%endmacro
+%imacro default 1+.nolist
+[default %1]
+%endmacro
+
; NASM compatibility shim
%define __OUTPUT_FORMAT__ __YASM_OBJFMT__