This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (23/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 02:54:30 -0700
- Subject: Thumb32 assembler (23/69)
With a couple more Ixx operand parse codes, we can convert the rest of
the iWMMXt and Maverick instructions, and get rid of check_iwmxxt_insn
entirely.
zw
* config/tc-arm.c (OP_I7, OP_Is63): New operand parse codes.
(parse_operands): Handle them.
(iwmmxt_insn_type, check_iwmmxt_insn): Delete.
(do_mav_shift): Rename encode_mav_shift. Take no arguments.
Expect inst.operands[] to be set up already.
(do_iwmmxt_textrc, do_iwmmxt_textrm, do_iwmmxt_tinsr, do_iwmmxt_waligni)
(do_iwmmxt_wshufh, do_mav_shift_1, do_mav_shift_2): Use parse_operands.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 24)
+++ gas/config/tc-arm.c (revision 25)
@@ -338,16 +338,6 @@
#define PSR_s (1 << 18)
#define PSR_f (1 << 19)
-
-enum iwmmxt_insn_type
-{
- check_tinsr,
- check_textrc,
- check_waligni,
- check_textrm,
- check_wshufh
-};
-
/* These values are the bit offsets of the register fields, allowing these
to be used directly in encoding operations. */
enum vfp_dp_reg_pos
@@ -4343,12 +4333,14 @@
#define OP_iEXP 025 /* same, with optional immediate prefix */
#define OP_I0 026 /* immediate value 0 */
#define OP_I4 027 /* 1 .. 4 */
-#define OP_I15 030 /* 0 .. 15 */
-#define OP_I16 031 /* 1 .. 16 */
-#define OP_I31 032 /* 0 .. 31 */
-#define OP_I32 033 /* 1 .. 32 */
-#define OP_I255 034 /* 0 .. 255 */
-#define OP_Iffff 035 /* 0 .. 65535 */
+#define OP_I7 030 /* 0 .. 7 */
+#define OP_I15 031 /* 0 .. 15 */
+#define OP_I16 032 /* 1 .. 16 */
+#define OP_I31 033 /* 0 .. 31 */
+#define OP_I32 034 /* 1 .. 32 */
+#define OP_Is63 035 /* -64 .. 63 */
+#define OP_I255 036 /* 0 .. 255 */
+#define OP_Iffff 037 /* 0 .. 65535 */
/* Macro for referring to one of the above constants as a number.
Should appear solely in parse_operands(). */
@@ -4444,10 +4436,12 @@
/* Immediates */
case OP_(I0): po_imm_or_fail (0, 0); break;
case OP_(I4): po_imm_or_fail (1, 4); break;
+ case OP_(I7): po_imm_or_fail (0, 7); break;
case OP_(I15): po_imm_or_fail (0, 15); break;
case OP_(I16): po_imm_or_fail (1, 16); break;
case OP_(I31): po_imm_or_fail (0, 31); break;
case OP_(I32): po_imm_or_fail (1, 32); break;
+ case OP_(Is63): po_imm_or_fail (-64, 63); break;
case OP_(I255): po_imm_or_fail (0, 255); break;
case OP_(Iffff): po_imm_or_fail (0, 0xffff); break;
@@ -7830,81 +7824,6 @@
/* iWMMXt instructions: strictly in alphabetical order. */
-/* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE
- immediate. */
-
-static unsigned long
-check_iwmmxt_insn (char * str,
- enum iwmmxt_insn_type insn_type,
- int immediate_size)
-{
- int reg = 0;
- int number;
- const char * inst_error;
-
- inst_error = inst.error;
- if (!inst.error)
- inst.error = BAD_ARGS;
- switch (insn_type)
- {
- case check_tinsr:
- if ((reg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL
- || reg_required_here (&str, 12, REG_TYPE_RN) == FAIL
- || skip_past_comma (&str) == FAIL))
- return FAIL;
- break;
-
- case check_textrc:
- if ((reg_required_here (&str, 12, REG_TYPE_RN) == FAIL
- || skip_past_comma (&str) == FAIL))
- return FAIL;
- break;
-
- case check_waligni:
- if ((reg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL
- || reg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL
- || reg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL))
- return FAIL;
- break;
-
- case check_textrm:
- if ((reg_required_here (&str, 12, REG_TYPE_RN) == FAIL
- || skip_past_comma (&str) == FAIL
- || reg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL))
- return FAIL;
- break;
-
- case check_wshufh:
- if ((reg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL
- || reg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
- || skip_past_comma (&str) == FAIL))
- return FAIL;
- break;
- }
-
- if (immediate_size == 0)
- {
- end_of_line (str);
- inst.error = inst_error;
- return reg;
- }
- else
- {
- if (immediate_required_here (&str, &number, 0,
- immediate_size, FALSE) == FAIL)
- return FAIL;
- end_of_line (str);
- inst.error = inst_error;
- return number;
- }
-}
-
static void
do_iwmmxt_tandorc (char * str)
{
@@ -7932,37 +7851,33 @@
static void
do_iwmmxt_textrc (char * str)
{
- unsigned long number;
-
- if ((number = check_iwmmxt_insn (str, check_textrc, 7))
- == (unsigned long) FAIL)
+ if (parse_operands (str, OPERANDS2(RR,I7)))
return;
- inst.instruction |= number & 0x7;
+ inst.instruction |= (inst.operands[0].reg << 12);
+ inst.instruction |= inst.operands[1].imm;
}
static void
do_iwmmxt_textrm (char * str)
{
- unsigned long number;
-
- if ((number = check_iwmmxt_insn (str, check_textrm, 7))
- == (unsigned long) FAIL)
+ if (parse_operands (str, OPERANDS3(RR,RIWR,I7)))
return;
- inst.instruction |= number & 0x7;
+ inst.instruction |= (inst.operands[0].reg << 12);
+ inst.instruction |= (inst.operands[1].reg << 16);
+ inst.instruction |= inst.operands[2].imm;
}
static void
do_iwmmxt_tinsr (char * str)
{
- unsigned long number;
-
- if ((number = check_iwmmxt_insn (str, check_tinsr, 7))
- == (unsigned long) FAIL)
+ if (parse_operands (str, OPERANDS3(RIWR,RR,I7)))
return;
- inst.instruction |= number & 0x7;
+ inst.instruction |= (inst.operands[0].reg << 16);
+ inst.instruction |= (inst.operands[1].reg << 12);
+ inst.instruction |= inst.operands[2].imm;
}
static void
@@ -8032,13 +7947,13 @@
static void
do_iwmmxt_waligni (char * str)
{
- unsigned long number;
-
- if ((number = check_iwmmxt_insn (str, check_waligni, 7))
- == (unsigned long) FAIL)
+ if (parse_operands (str, OPERANDS4(RIWR,RIWR,RIWR,I7)))
return;
- inst.instruction |= ((number & 0x7) << 20);
+ inst.instruction |= (inst.operands[0].reg << 12);
+ inst.instruction |= (inst.operands[1].reg << 16);
+ inst.instruction |= (inst.operands[2].reg << 0);
+ inst.instruction |= (inst.operands[3].imm << 20);
}
static void
@@ -8131,13 +8046,13 @@
static void
do_iwmmxt_wshufh (char * str)
{
- unsigned long number;
-
- if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff))
- == (unsigned long) FAIL)
+ if (parse_operands (str, OPERANDS3(RIWR,RIWR,I255)))
return;
- inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
+ inst.instruction |= (inst.operands[0].reg << 12);
+ inst.instruction |= (inst.operands[1].reg << 16);
+ inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
+ inst.instruction |= (inst.operands[2].imm & 0x0f);
}
static void
@@ -8438,70 +8353,35 @@
cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
static void
-do_mav_shift (char * str,
- enum arm_reg_type reg0,
- enum arm_reg_type reg1)
+encode_mav_shift (void)
{
- int imm, neg = 0;
+ int imm = inst.operands[2].imm;
- reg_or_fail (&str, 12, reg0);
- comma_or_fail (&str);
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 16;
- reg_or_fail (&str, 16, reg1);
- comma_or_fail (&str);
-
- /* Calculate the immediate operand.
- The operand is a 7bit signed number. */
- if (*str == '#')
- ++str;
-
- if (!ISDIGIT (*str) && *str != '-')
- {
- inst.error = _("expecting immediate, 7bit operand");
- return;
- }
-
- if (*str == '-')
- {
- neg = 1;
- ++str;
- }
-
- for (imm = 0; *str && ISDIGIT (*str); ++str)
- imm = imm * 10 + *str - '0';
-
- if (imm > 64)
- {
- inst.error = _("immediate out of range");
- return;
- }
-
- /* Make negative imm's into 7bit signed numbers. */
- if (neg)
- {
- imm = -imm;
- imm &= 0x0000007f;
- }
-
/* Bits 0-3 of the insn should have bits 0-3 of the immediate.
Bits 5-7 of the insn should have bits 4-6 of the immediate.
Bit 4 should be 0. */
imm = (imm & 0xf) | ((imm & 0x70) << 1);
inst.instruction |= imm;
- end_of_line (str);
}
static void
-do_mav_shift_1 (char * str)
+do_mav_shift_1 (char *str)
{
- do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
+ if (parse_operands (str, OPERANDS3(RMFX,RMFX,Is63)))
+ return;
+ encode_mav_shift ();
}
static void
do_mav_shift_2 (char * str)
{
- do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
+ if (parse_operands (str, OPERANDS3(RMDX,RMDX,Is63)))
+ return;
+ encode_mav_shift ();
}
/* Maverick load/store instructions.