+2019-06-27 Barnaby Wilk s<barnaby.wilks@arm.com>
+
+ * config/tc-arm.c (do_smc): Add range check for immediate operand.
+ (do_t_smc): Add range check for immediate operand. Remove
+ obsolete immediate encoding.
+ (md_apply_fix): Fix range check. Remove obsolete immediate encoding.
+ * testsuite/gas/arm/arch6zk.d: Fix test.
+ * testsuite/gas/arm/arch6zk.s: Fix test.
+ * testsuite/gas/arm/smc-bad.d: New test.
+ * testsuite/gas/arm/smc-bad.l: New test.
+ * testsuite/gas/arm/smc-bad.s: New test.
+ * testsuite/gas/arm/thumb32.d: Fix test.
+ * testsuite/gas/arm/thumb32.s: Fix test.
+
2019-06-27 Jan Beulich <jbeulich@suse.com>
config/tc-i386.c (md_assemble): Check for protected mode
static void
do_smc (void)
{
+ unsigned int value = inst.relocs[0].exp.X_add_number;
+ constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
+
inst.relocs[0].type = BFD_RELOC_ARM_SMC;
inst.relocs[0].pc_rel = 0;
}
_("SMC is not permitted on this architecture"));
constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
+ constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
+
inst.relocs[0].type = BFD_RELOC_UNUSED;
- inst.instruction |= (value & 0xf000) >> 12;
- inst.instruction |= (value & 0x0ff0);
inst.instruction |= (value & 0x000f) << 16;
+
/* PR gas/15623: SMC instructions must be last in an IT block. */
set_pred_insn_type_last ();
}
break;
case BFD_RELOC_ARM_SMC:
- if (((unsigned long) value) > 0xffff)
+ if (((unsigned long) value) > 0xf)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("invalid smc expression"));
+
newval = md_chars_to_number (buf, INSN_SIZE);
- newval |= (value & 0xf) | ((value & 0xfff0) << 4);
+ newval |= (value & 0xf);
md_number_to_chars (buf, newval, INSN_SIZE);
break;
0+040 <[^>]*> e320f002 ? wfe
0+044 <[^>]*> e320f003 ? wfi
0+048 <[^>]*> e320f001 ? yield
-0+04c <[^>]*> e16ec371 ? smc 60465.*
-0+050 <[^>]*> 11613c7e ? smcne 5070.*
+0+04c <[^>]*> e1600071 ? smc 1.*
+0+050 <[^>]*> 1160007e ? smcne 14.*
#...
wfi
yield
# ARMV6Z instructions
- smc 0xec31
- smcne 0x13ce
+ smc 0x1
+ smcne 0xe
# Ensure output is 32-byte aligned as required for arm-aout.
.p2align 5
--- /dev/null
+# name: Invalid SMC operand test
+# source: smc-bad.s
+# error_output: smc-bad.l
--- /dev/null
+.*smc-bad.s: Assembler messages:
+.*smc-bad.s:2: Error: immediate too large \(bigger than 0xF\) -- `smc #0xfefe'
+.*smc-bad.s:3: Error: immediate too large \(bigger than 0xF\) -- `smc #0x12'
+.*smc-bad.s:4: Error: immediate too large \(bigger than 0xF\) -- `smc 123'
+.*smc-bad.s:7: Error: immediate too large \(bigger than 0xF\) -- `smc #0xdfd'
+.*smc-bad.s:8: Error: immediate too large \(bigger than 0xF\) -- `smc #0x43'
+.*smc-bad.s:9: Error: immediate too large \(bigger than 0xF\) -- `smc 4343343'
+.*smc-bad.s:14: Error: immediate too large \(bigger than 0xF\) -- `smc #0x6951'
--- /dev/null
+.arm
+ smc #0xfefe
+ smc #0x12
+ smc 123
+
+.thumb
+ smc #0xdfd
+ smc #0x43
+ smc 4343343
+
+.arm
+.syntax unified
+.cpu cortex-a8
+ smc #0x6951
0[0-9a-f]+ <[^>]+> ea4f 0132 mov.w r1, r2, rrx
0[0-9a-f]+ <[^>]+> ea5f 0334 movs.w r3, r4, rrx
0[0-9a-f]+ <[^>]+> f7f0 8000 smc #0
-0[0-9a-f]+ <[^>]+> f7fd 8bca smc #43981 ; 0xabcd
+0[0-9a-f]+ <[^>]+> f7fd 8000 smc #13
0[0-9a-f]+ <[^>]+> fb10 0000 smlabb r0, r0, r0, r0
0[0-9a-f]+ <[^>]+> fb10 0900 smlabb r9, r0, r0, r0
0[0-9a-f]+ <[^>]+> fb19 0000 smlabb r0, r9, r0, r0
.arch_extension sec
smc:
smc #0
- smc #0xabcd
+ smc #0xd
smla:
smlabb r0, r0, r0, r0