This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] New GAS directives to encode instructions
- From: Daniel Gutson <dgutson at codesourcery dot com>
- To: binutils at sourceware dot org, Nick Clifton <nickc at redhat dot com>
- Date: Tue, 07 Jul 2009 19:02:26 -0300
- Subject: Re: [PATCH] New GAS directives to encode instructions
- References: <4A53BFB2.4030006@codesourcery.com>
My apologizes, wrong patch version.
I would fix myself if I would have my source code, but my brainware is
not Free Software unfortunately.
ChangeLog is the same.
Daniel.
Daniel Gutson wrote:
Hi,
the attached patch adds a new .inst directives family to generate an
instruction from its integer encoding.
The added directives are:
.inst (Thumb and ARM)
.inst.w (Thumb only)
.inst.n (Thumb only).
Please refer to the changes in c-arm.texi for further details.
I tested this with the gas test suite, including the test cases I added.
Please commit it for me since I don't have write access, if accepted.
Thanks!
Daniel.
-----
2009-07-07 Daniel Gutson <dgutson@codesourcery.com>
gas/
* config/tc-arm.c (it_fsm_post_encode): New forward declaration.
(set_it_insn_type_nonvoid): New macro.
(emit_thumb32_expr): New function.
(thumb_insn_size): New function.
(emit_insn): New function.
(s_arm_elf_inst): New function.
(md_pseudo_table): New pseudo-opcode entries added.
* doc/c-arm.texi: New directive added.
gas/testsuite/
* gas/arm/inst-po.d: New testcase.
* gas/arm/inst-po.s: New file.
* gas/arm/inst-po-2.d: New testcase.
* gas/arm/inst-po-2.s: New file.
* gas/arm/inst-po-2.l: New file.
* gas/arm/inst-po-3.d: New testcase.
* gas/arm/inst-po-3.s: New file.
* gas/arm/inst-po-be.d: New testcase.
--
Daniel Gutson
CodeSourcery
dgutson@codesourcery.com
? inst_mailine_good.patch
? inst_mainline.patch
? inst_mainline_good.patch
? tcarm.patch
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.392
diff -u -p -r1.392 tc-arm.c
--- gas/config/tc-arm.c 7 Jul 2009 16:15:30 -0000 1.392
+++ gas/config/tc-arm.c 7 Jul 2009 21:59:12 -0000
@@ -766,6 +766,8 @@ static int handle_it_state (void);
static void force_automatic_it_block_close (void);
+static void it_fsm_post_encode (void);
+
#define set_it_insn_type(type) \
do \
{ \
@@ -775,6 +777,13 @@ static void force_automatic_it_block_clo
} \
while (0)
+#define set_it_insn_type_nonvoid(type, failret) \
+ do{ \
+ inst.it_insn_type = type; \
+ if (handle_it_state () == FAIL) \
+ return failret; \
+ }while(0)
+
#define set_it_insn_type_last() \
do \
{ \
@@ -3108,6 +3117,129 @@ s_arm_elf_cons (int nbytes)
demand_empty_rest_of_line ();
}
+/* Emit an expression containing a 32-bit thumb instruction.
+ Implementation based on put_thumb32_insn. */
+static void
+emit_thumb32_expr (expressionS *exp)
+{
+ expressionS exp_high = *exp;
+ exp_high.X_add_number = (unsigned long)exp_high.X_add_number
+ >> 16;
+ emit_expr (&exp_high, (unsigned int) THUMB_SIZE);
+ exp->X_add_number &= 0xffff;
+ emit_expr (exp, (unsigned int) THUMB_SIZE);
+}
+
+/* Guess the instruction size based on the opcode. */
+static int
+thumb_insn_size(int opcode)
+{
+ if ((unsigned int)opcode < 0xe800u)
+ return 2;
+ else if ((unsigned int) opcode >= 0xe8000000u)
+ return 4;
+ else
+ return 0;
+}
+
+static int
+emit_insn (expressionS *exp, int nbytes)
+{
+ int size = 0;
+
+ if (exp->X_op == O_constant)
+ {
+ size = nbytes;
+
+ if (size == 0)
+ size = thumb_insn_size (exp->X_add_number);
+
+ if (size != 0)
+ {
+ if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
+ {
+ as_bad (_(".inst.n operand too big. "\
+ "Use .inst.w instead"));
+ size = 0;
+ }
+ else
+ {
+ if (now_it.state == AUTOMATIC_IT_BLOCK)
+ set_it_insn_type_nonvoid (OUTSIDE_IT_INSN, 0);
+ else
+ set_it_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
+
+ if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
+ emit_thumb32_expr (exp);
+ else
+ emit_expr (exp, (unsigned int) size);
+
+ it_fsm_post_encode ();
+ }
+ }
+ else
+ {
+ as_bad (_("cannot determine Thumb instruction size. "\
+ "Use .inst.n/.inst.w instead"));
+ }
+ }
+ else
+ {
+ as_bad (_("constant expression required"));
+ }
+
+ return (size != 0);
+}
+
+/* Like s_arm_elf_cons but do not use md_cons_align and
+ set the mapping state to MAP_ARM/MAP_THUMB. */
+
+static void
+s_arm_elf_inst (int nbytes)
+{
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* Calling mappint_state () here will not change ARM/THUMB, but
+ will ensure not to be in DATA state. */
+
+ if (thumb_mode)
+ mapping_state (MAP_THUMB);
+ else
+ {
+ if (nbytes != 0)
+ {
+ as_bad (_("width suffixes are invalid in ARM mode"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ nbytes = 4;
+
+ mapping_state (MAP_ARM);
+ }
+
+ do
+ {
+ expressionS exp;
+
+ expression (&exp);
+
+ if (!emit_insn (&exp, nbytes))
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* Put terminator back into stream. */
+ input_line_pointer --;
+ demand_empty_rest_of_line ();
+}
/* Parse a .rel31 directive. */
@@ -4067,9 +4199,12 @@ const pseudo_typeS md_pseudo_table[] =
{ "object_arch", s_arm_object_arch, 0 },
{ "fpu", s_arm_fpu, 0 },
#ifdef OBJ_ELF
- { "word", s_arm_elf_cons, 4 },
- { "long", s_arm_elf_cons, 4 },
- { "rel31", s_arm_rel31, 0 },
+ { "word", s_arm_elf_cons, 4 },
+ { "long", s_arm_elf_cons, 4 },
+ { "inst.n", s_arm_elf_inst, 2 },
+ { "inst.w", s_arm_elf_inst, 4 },
+ { "inst", s_arm_elf_inst, 0 },
+ { "rel31", s_arm_rel31, 0 },
{ "fnstart", s_arm_unwind_fnstart, 0 },
{ "fnend", s_arm_unwind_fnend, 0 },
{ "cantunwind", s_arm_unwind_cantunwind, 0 },
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-arm.texi,v
retrieving revision 1.57
diff -u -p -r1.57 c-arm.texi
--- gas/doc/c-arm.texi 22 Jun 2009 14:40:27 -0000 1.57
+++ gas/doc/c-arm.texi 7 Jul 2009 21:59:12 -0000
@@ -569,6 +569,15 @@ Must be preceded by a @code{.personality
directive.
@c IIIIIIIIIIIIIIIIIIIIIIIIII
+
+@cindex @code{.inst} directive, ARM
+@item .inst @var{opcode} [ , @dots{} ]
+@item .inst.n @var{opcode} [ , @dots{} ]
+@item .inst.w @var{opcode} [ , @dots{} ]
+Generates the instruction corresponding to the @var{opcode}.
+@code{.inst.n} and @code{.inst.w} allow the Thumb instruction size to be
+specified explicitly, overriding the normal encoding rules.
+
@c JJJJJJJJJJJJJJJJJJJJJJJJJJ
@c KKKKKKKKKKKKKKKKKKKKKKKKKK
@c LLLLLLLLLLLLLLLLLLLLLLLLLL
Index: gas/testsuite/gas/arm/inst-po-2.d
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po-2.d
diff -N gas/testsuite/gas/arm/inst-po-2.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po-2.d 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,4 @@
+#name: .inst pseudo-opcode validations test
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#error-output: inst-po-2.l
Index: gas/testsuite/gas/arm/inst-po-2.l
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po-2.l
diff -N gas/testsuite/gas/arm/inst-po-2.l
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po-2.l 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,6 @@
+[^:]*: Assembler messages:
+[^:]*:7: Error: constant expression required
+[^:]*:10: Error: width suffixes are invalid in ARM mode
+[^:]*:11: Error: width suffixes are invalid in ARM mode
+[^:]*:14: Error: cannot determine Thumb instruction size. Use .inst.n/.inst.w instead
+[^:]*:15: Error: .inst.n operand too big. Use .inst.w instead
Index: gas/testsuite/gas/arm/inst-po-2.s
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po-2.s
diff -N gas/testsuite/gas/arm/inst-po-2.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po-2.s 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,16 @@
+.syntax unified
+.arch armv7a
+.arm
+.L1:
+
+moveq r1, r9
+.inst .L1
+
+.arm
+.inst.w 1
+.inst.n 1
+
+.thumb
+.inst 0xf000
+.inst.n 1<<31
+
Index: gas/testsuite/gas/arm/inst-po-3.d
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po-3.d
diff -N gas/testsuite/gas/arm/inst-po-3.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po-3.d 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,16 @@
+#name: .inst pseudo-opcode with automatic IT blocks test
+#as: -mimplicit-it=always
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <.text> bf08 it eq
+00000002 <.text\+0x2> 4649 moveq r1, r9
+00000004 <.text\+0x4> 4649 mov r1, r9
+00000006 <.text\+0x6> 4649 mov r1, r9
+00000008 <.text\+0x8> 00001234 .word 0x00001234
+0000000c <.text\+0xc> bf0c ite eq
+0000000e <.text\+0xe> 4649 moveq r1, r9
+00000010 <.text\+0x10> 4649 movne r1, r9
Index: gas/testsuite/gas/arm/inst-po-3.s
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po-3.s
diff -N gas/testsuite/gas/arm/inst-po-3.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po-3.s 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,17 @@
+.syntax unified
+.arch armv7a
+.thumb
+
+@ it eq
+@ mov r1, r9
+@ mov r1, r9
+moveq r1, r9
+.inst 0x4649
+.inst 0x4649
+
+.word 0x1234
+
+@ ite eq
+@ moveq r1, r9
+@ movne r1, r9
+.inst 0xbf0b + 1, 0x4649, 0x4649
Index: gas/testsuite/gas/arm/inst-po-be.d
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po-be.d
diff -N gas/testsuite/gas/arm/inst-po-be.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po-be.d 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,21 @@
+#name: .inst pseudo-opcode test 1 - big endian version
+#as: -mbig-endian
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#source: inst-po.s
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <.text> 11a01009 movne r1, r9
+00000004 <.text\+0x4> bf0c ite eq
+00000006 <.text\+0x6> 4649 moveq r1, r9
+00000008 <.text\+0x8> 4649 movne r1, r9
+0000000a <.text\+0xa> 0000 .short 0x0000
+0000000c <.text\+0xc> 1234 .short 0x1234
+0000000e <.text\+0xe> bf0c ite eq
+00000010 <.text\+0x10> 4649 moveq r1, r9
+00000012 <.text\+0x12> 4649 movne r1, r9
+00000014 <.text\+0x14> 4649 mov r1, r9
+00000016 <.text\+0x16> ea4f 0109 mov.w r1, r9
+0000001a <.text\+0x1a> ea4f 0109 mov.w r1, r9
Index: gas/testsuite/gas/arm/inst-po.d
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po.d
diff -N gas/testsuite/gas/arm/inst-po.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po.d 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,19 @@
+#name: .inst pseudo-opcode test 1
+#objdump: -d --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <.text> 11a01009 movne r1, r9
+00000004 <.text\+0x4> bf0c ite eq
+00000006 <.text\+0x6> 4649 moveq r1, r9
+00000008 <.text\+0x8> 4649 movne r1, r9
+0000000a <.text\+0xa> 1234 .short 0x1234
+0000000c <.text\+0xc> 0000 .short 0x0000
+0000000e <.text\+0xe> bf0c ite eq
+00000010 <.text\+0x10> 4649 moveq r1, r9
+00000012 <.text\+0x12> 4649 movne r1, r9
+00000014 <.text\+0x14> 4649 mov r1, r9
+00000016 <.text\+0x16> ea4f 0109 mov.w r1, r9
+0000001a <.text\+0x1a> ea4f 0109 mov.w r1, r9
Index: gas/testsuite/gas/arm/inst-po.s
===================================================================
RCS file: gas/testsuite/gas/arm/inst-po.s
diff -N gas/testsuite/gas/arm/inst-po.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/inst-po.s 7 Jul 2009 21:59:12 -0000
@@ -0,0 +1,27 @@
+.syntax unified
+.arch armv7a
+.arm
+@ movne r1,r9
+.inst 0x11a01009
+
+.thumb
+
+@ ite eq
+@ moveq r1, r9
+@ movne r1, r9
+.inst 0xbf0b + 1, 0x4649
+.inst 0x4649
+
+.word 0x1234
+
+@ ite eq
+@ moveq r1, r9
+@ movne r1, r9
+.inst.n 0xbf0b + 1, 0x4649, 0x4649
+
+.inst.n 0x4649
+
+@ mov.w r1, r9
+@ mov.w r1, r9
+.inst 0xea4f0109
+.inst.w 0xea4f0109