This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
gas/arm: clean up register name parsing.
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: binutils at sources dot redhat dot com
- Cc: Richard dot Earnshaw at arm dot com, nickc at redhat dot com, aldyh at redhat dot com
- Date: Wed, 09 Jan 2002 16:50:31 +0000
- Subject: gas/arm: clean up register name parsing.
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
In order to get this patch to work I've had to reverse-engineer the cirrus
maverick instructions using the tests in the testsuite, since there
doesn't seem to be any public documentation of these instructions. So I'm
working on the assumption that those tests are correct and that they
provide adequate coverage of the syntax of those instructions. The tests
still pass after this patch has been applied.
This patch splits the existing register names table into several smaller
tables, one for each class of register; each entry can then contain the
real register number rather than some offset that has to be mangled to
extract the real value. In all arm instructions, the class of register
that is acceptable is always defined by the context at that point of
parsing, so we should never need to look up a register in more than one
table.
I've also fixed all the Maverick support routines so that they now impose
the register class constraints (as determined from the testsuite). So we
should now get an error if an invalid register name is used.
The support routines for the Maverick functions could now be more usefully
renamed to match the type of instruction, but without knowing what they
all do it's a little hard to think of sensible names. Aldy, perhaps you
could come up with a further patch to apply on top of this one that does
this.
<date> Richard Earnshaw (rearnsha@arm.com)
* tc-arm.c (struct reg_entry): Move before prototypes.
(int_register, cp_register, fp_register): Delete.
(reg_table): Delete. Replaced with ...
(rn_table, cp_table, cn_table, fn_table, mav_mvf_table)
(mav_mvd_table, mav_mvfx_table, mav_mvdx_table, mav_mvax_table)
(mav_dspsc_table): ... one table per register set.
(arm_reg_hsh): Delete.
(struct reg_map): New structure.
(all_reg_maps): New array.
(enum arm_reg_type): New enums.
(build_reg_hsh): New function.
(insert_reg_alias): Use hash table passed by caller. Adjust all
callers.
(create_register_alias): New function, split out from ...
(md_assemble): ... here.
(md_begin): Build new register hash tables.
(arm_reg_parse): New argument for the hash table to search.
Adjust all
callers.
(arm_reg_parse_any): New function.
(co_proc_number): Look up the processor number in the processor
hash
table.
(cirrus_regtype): Delete.
(cirrus_register, cirrus_mvf_register, cirrus_mvd_register)
(cirrus_mvfx_register, cirrus_mvdx_register, cirrus_mvax_register)
(ARM_EXT_MAVERICKsc_register): Delete.
(do_c_binops_1, do_c_binops_2, do_c_binops_3): Delete.
(do_c_binops_1[a-o], do_c_binops_2[a-c], do_c_binops_3[a-d]): New
functions.
(do_c_triple_4, do_c_triple_5): Delete.
(do_c_triple_4[ab], do_c_triple_5[a-h]): New functions.
(do_c_quad_6): Delete.
(do_c_quad_6[ab]): New functions.
(do_c_binops, do_c_triple, do_c_quad, do_c_shift, do_c_ldst): Rework
arguments to use new register parsing methods.
(cirrus_reg_required_here): Likewise.
(insns): Reclassify cirrus maverick worker functions.
(cirrus_valid_reg): Delete.
Index: tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.105
diff -p -r1.105 tc-arm.c
*** tc-arm.c 2001/12/06 10:23:20 1.105
--- tc-arm.c 2002/01/09 16:16:10
*************** static const struct asm_psr psrs[] =
*** 468,484 ****
{"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
};
! enum cirrus_regtype
! {
! CIRRUS_REGTYPE_MVF = 1,
! CIRRUS_REGTYPE_MVFX = 2,
! CIRRUS_REGTYPE_MVD = 3,
! CIRRUS_REGTYPE_MVDX = 4,
! CIRRUS_REGTYPE_MVAX = 5,
! CIRRUS_REGTYPE_DSPSC = 6,
! CIRRUS_REGTYPE_ANY = 7
! };
/* Functions called by parser. */
/* ARM instructions. */
static void do_arit PARAMS ((char *));
--- 468,625 ----
{"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
};
! /* Structure for a hash table entry for a register. */
! struct reg_entry
! {
! const char * name;
! int number;
! };
!
! #define REG_SP 13
! #define REG_LR 14
! #define REG_PC 15
!
! /* These are the standard names. Users can add aliases with .req. */
! /* Integer Register Numbers. */
! static const struct reg_entry rn_table[] =
! {
! {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
! {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
! {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
! {"r12", 12}, {"r13", REG_SP}, {"r14", REG_LR}, {"r15", REG_PC},
! /* ATPCS Synonyms. */
! {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
! {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7},
! {"v5", 8}, {"v6", 9}, {"v7", 10}, {"v8", 11},
! /* Well-known aliases. */
! {"wr", 7},
! {"sb", 9}, {"sl", 10}, {"fp", 11},
! {"ip", 12}, {"sp", REG_SP}, {"lr", REG_LR}, {"pc", REG_PC},
! {NULL, 0}
! };
!
! /* Co-processor Numbers. */
! static const struct reg_entry cp_table[] =
! {
! {"p0", 0}, {"p1", 1}, {"p2", 2}, {"p3", 3},
! {"p4", 4}, {"p5", 5}, {"p6", 6}, {"p7", 7},
! {"p8", 8}, {"p9", 9}, {"p10", 10}, {"p11", 11},
! {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
! {NULL, 0}
! };
!
! /* Co-processor Register Numbers. */
! static const struct reg_entry cn_table[] =
! {
! {"c0", 0}, {"c1", 1}, {"c2", 2}, {"c3", 3},
! {"c4", 4}, {"c5", 5}, {"c6", 6}, {"c7", 7},
! {"c8", 8}, {"c9", 9}, {"c10", 10}, {"c11", 11},
! {"c12", 12}, {"c13", 13}, {"c14", 14}, {"c15", 15},
! /* Not really valid, but kept for back-wards compatibility. */
! {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
! {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
! {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
! {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
! {NULL, 0}
! };
!
! /* FPA Registers. */
! static const struct reg_entry fn_table[] =
! {
! {"f0", 0}, {"f1", 1}, {"f2", 2}, {"f3", 3},
! {"f4", 4}, {"f5", 5}, {"f6", 6}, {"f7", 7},
! {NULL, 0}
! };
!
! /* Cirrus DSP coprocessor registers. */
! static const struct reg_entry mav_mvf_table[] =
! {
! {"mvf0", 0}, {"mvf1", 1}, {"mvf2", 2}, {"mvf3", 3},
! {"mvf4", 4}, {"mvf5", 5}, {"mvf6", 6}, {"mvf7", 7},
! {"mvf8", 8}, {"mvf9", 9}, {"mvf10", 10}, {"mvf11", 11},
! {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
! {NULL, 0}
! };
!
! static const struct reg_entry mav_mvd_table[] =
! {
! {"mvd0", 0}, {"mvd1", 1}, {"mvd2", 2}, {"mvd3", 3},
! {"mvd4", 4}, {"mvd5", 5}, {"mvd6", 6}, {"mvd7", 7},
! {"mvd8", 8}, {"mvd9", 9}, {"mvd10", 10}, {"mvd11", 11},
! {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
! {NULL, 0}
! };
!
! static const struct reg_entry mav_mvfx_table[] =
! {
! {"mvfx0", 0}, {"mvfx1", 1}, {"mvfx2", 2}, {"mvfx3", 3},
! {"mvfx4", 4}, {"mvfx5", 5}, {"mvfx6", 6}, {"mvfx7", 7},
! {"mvfx8", 8}, {"mvfx9", 9}, {"mvfx10", 10}, {"mvfx11", 11},
! {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
! {NULL, 0}
! };
!
! static const struct reg_entry mav_mvdx_table[] =
! {
! {"mvdx0", 0}, {"mvdx1", 1}, {"mvdx2", 2}, {"mvdx3", 3},
! {"mvdx4", 4}, {"mvdx5", 5}, {"mvdx6", 6}, {"mvdx7", 7},
! {"mvdx8", 8}, {"mvdx9", 9}, {"mvdx10", 10}, {"mvdx11", 11},
! {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
! {NULL, 0}
! };
!
! static const struct reg_entry mav_mvax_table[] =
! {
! {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
! {NULL, 0}
! };
!
! static const struct reg_entry mav_dspsc_table[] =
! {
! {"dspsc", 0},
! {NULL, 0}
! };
!
! struct reg_map
! {
! const struct reg_entry *names;
! int max_regno;
! struct hash_control *htab;
! const char *expected;
! };
!
! struct reg_map all_reg_maps[] =
! {
! {rn_table, 15, NULL, N_("ARM register expected")},
! {cp_table, 15, NULL, N_("Bad or missing co-processor number")},
! {cn_table, 15, NULL, N_("Co-processor register expected")},
! {fn_table, 7, NULL, N_("FPA register expected")},
! {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
! {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
! {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
! {mav_mvdx_table, 15, NULL, N_("Maverick MVFX register expected")},
! {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
! {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
! };
!
! /* Enumeration matching entries in table above. */
! enum arm_reg_type
! {
! REG_TYPE_RN = 0,
! #define REG_TYPE_FIRST REG_TYPE_RN
! REG_TYPE_CP = 1,
! REG_TYPE_CN = 2,
! REG_TYPE_FN = 3,
! REG_TYPE_MVF = 4,
! REG_TYPE_MVD = 5,
! REG_TYPE_MVFX = 6,
! REG_TYPE_MVDX = 7,
! REG_TYPE_MVAX = 8,
! REG_TYPE_DSPSC = 9,
+ REG_TYPE_MAX = 10
+ };
+
/* Functions called by parser. */
/* ARM instructions. */
static void do_arit PARAMS ((char *));
*************** static void do_mar PARAMS ((char *));
*** 555,588 ****
static void do_mra PARAMS ((char *));
/* Maverick. */
! static void do_c_binops PARAMS ((char *, int));
! static void do_c_binops_1 PARAMS ((char *));
! static void do_c_binops_2 PARAMS ((char *));
! static void do_c_binops_3 PARAMS ((char *));
! static void do_c_triple PARAMS ((char *, int));
! static void do_c_triple_4 PARAMS ((char *));
! static void do_c_triple_5 PARAMS ((char *));
! static void do_c_quad PARAMS ((char *, int));
! static void do_c_quad_6 PARAMS ((char *));
! static void do_c_dspsc PARAMS ((char *, int));
static void do_c_dspsc_1 PARAMS ((char *));
static void do_c_dspsc_2 PARAMS ((char *));
! static void do_c_shift PARAMS ((char *, int));
static void do_c_shift_1 PARAMS ((char *));
static void do_c_shift_2 PARAMS ((char *));
! static void do_c_ldst PARAMS ((char *, int));
static void do_c_ldst_1 PARAMS ((char *));
static void do_c_ldst_2 PARAMS ((char *));
static void do_c_ldst_3 PARAMS ((char *));
static void do_c_ldst_4 PARAMS ((char *));
static int cirrus_reg_required_here PARAMS ((char **, int,
! enum cirrus_regtype));
! static int cirrus_valid_reg PARAMS ((int, enum cirrus_regtype));
static int cirrus_parse_offset PARAMS ((char **, int *));
static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
int, int));
! static int arm_reg_parse PARAMS ((char **));
static const struct asm_psr * arm_psr_parse PARAMS ((char **));
static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
fragS *));
--- 696,764 ----
static void do_mra PARAMS ((char *));
/* Maverick. */
! static void do_c_binops PARAMS ((char *, int, enum arm_reg_type,
! enum arm_reg_type));
! static void do_c_binops_1a PARAMS ((char *));
! static void do_c_binops_1b PARAMS ((char *));
! static void do_c_binops_1c PARAMS ((char *));
! static void do_c_binops_1d PARAMS ((char *));
! static void do_c_binops_1e PARAMS ((char *));
! static void do_c_binops_1f PARAMS ((char *));
! static void do_c_binops_1g PARAMS ((char *));
! static void do_c_binops_1h PARAMS ((char *));
! static void do_c_binops_1i PARAMS ((char *));
! static void do_c_binops_1j PARAMS ((char *));
! static void do_c_binops_1k PARAMS ((char *));
! static void do_c_binops_1l PARAMS ((char *));
! static void do_c_binops_1m PARAMS ((char *));
! static void do_c_binops_1n PARAMS ((char *));
! static void do_c_binops_1o PARAMS ((char *));
! static void do_c_binops_2a PARAMS ((char *));
! static void do_c_binops_2b PARAMS ((char *));
! static void do_c_binops_2c PARAMS ((char *));
! static void do_c_binops_3a PARAMS ((char *));
! static void do_c_binops_3b PARAMS ((char *));
! static void do_c_binops_3c PARAMS ((char *));
! static void do_c_binops_3d PARAMS ((char *));
! static void do_c_triple PARAMS ((char *, int, enum arm_reg_type,
! enum arm_reg_type,
! enum arm_reg_type));
! static void do_c_triple_4a PARAMS ((char *));
! static void do_c_triple_4b PARAMS ((char *));
! static void do_c_triple_5a PARAMS ((char *));
! static void do_c_triple_5b PARAMS ((char *));
! static void do_c_triple_5c PARAMS ((char *));
! static void do_c_triple_5d PARAMS ((char *));
! static void do_c_triple_5e PARAMS ((char *));
! static void do_c_triple_5f PARAMS ((char *));
! static void do_c_triple_5g PARAMS ((char *));
! static void do_c_triple_5h PARAMS ((char *));
! static void do_c_quad PARAMS ((char *, int, enum arm_reg_type,
! enum arm_reg_type,
! enum arm_reg_type,
! enum arm_reg_type));
! static void do_c_quad_6a PARAMS ((char *));
! static void do_c_quad_6b PARAMS ((char *));
static void do_c_dspsc_1 PARAMS ((char *));
static void do_c_dspsc_2 PARAMS ((char *));
! static void do_c_shift PARAMS ((char *, enum arm_reg_type,
! enum arm_reg_type));
static void do_c_shift_1 PARAMS ((char *));
static void do_c_shift_2 PARAMS ((char *));
! static void do_c_ldst PARAMS ((char *, enum arm_reg_type));
static void do_c_ldst_1 PARAMS ((char *));
static void do_c_ldst_2 PARAMS ((char *));
static void do_c_ldst_3 PARAMS ((char *));
static void do_c_ldst_4 PARAMS ((char *));
+
static int cirrus_reg_required_here PARAMS ((char **, int,
! enum arm_reg_type));
static int cirrus_parse_offset PARAMS ((char **, int *));
static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
int, int));
! static int arm_reg_parse PARAMS ((char **, struct hash_control *));
! static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
static const struct asm_psr * arm_psr_parse PARAMS ((char **));
static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
fragS *));
*************** static int decode_shift PARAMS ((char *
*** 613,625 ****
static int ldst_extend PARAMS ((char **));
static int ldst_extend_v4 PARAMS ((char **));
static void thumb_add_sub PARAMS ((char *, int));
! static void insert_reg PARAMS ((int));
static void thumb_shift PARAMS ((char *, int));
static void thumb_mov_compare PARAMS ((char *, int));
static void build_arm_ops_hsh PARAMS ((void));
static void set_constant_flonums PARAMS ((void));
static valueT md_chars_to_number PARAMS ((char *, int));
! static void insert_reg_alias PARAMS ((char *, int));
static void output_inst PARAMS ((void));
static int accum0_required_here PARAMS ((char **));
static int ld_mode_required_here PARAMS ((char **));
--- 789,804 ----
static int ldst_extend PARAMS ((char **));
static int ldst_extend_v4 PARAMS ((char **));
static void thumb_add_sub PARAMS ((char *, int));
! static void insert_reg PARAMS ((const struct reg_entry *,
! struct hash_control *));
static void thumb_shift PARAMS ((char *, int));
static void thumb_mov_compare PARAMS ((char *, int));
static void build_arm_ops_hsh PARAMS ((void));
static void set_constant_flonums PARAMS ((void));
static valueT md_chars_to_number PARAMS ((char *, int));
! static void build_reg_hsh PARAMS ((struct reg_map *));
! static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
! static int create_register_alias PARAMS ((char *, char *));
static void output_inst PARAMS ((void));
static int accum0_required_here PARAMS ((char **));
static int ld_mode_required_here PARAMS ((char **));
*************** static const struct asm_opcode insns[] =
*** 1312,1385 ****
{"cfstrd", 0xec400400, 6, ARM_EXT_MAVERICK, do_c_ldst_2},
{"cfstr32", 0xec000500, 7, ARM_EXT_MAVERICK, do_c_ldst_3},
{"cfstr64", 0xec400500, 7, ARM_EXT_MAVERICK, do_c_ldst_4},
! {"cfmvsr", 0xee000450, 6, ARM_EXT_MAVERICK, do_c_binops_2},
! {"cfmvrs", 0xee100450, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfmvdlr", 0xee000410, 7, ARM_EXT_MAVERICK, do_c_binops_2},
! {"cfmvrdl", 0xee100410, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfmvdhr", 0xee000430, 7, ARM_EXT_MAVERICK, do_c_binops_2},
! {"cfmvrdh", 0xee100430, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfmv64lr", 0xee000510, 8, ARM_EXT_MAVERICK, do_c_binops_2},
! {"cfmvr64l", 0xee100510, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfmv64hr", 0xee000530, 8, ARM_EXT_MAVERICK, do_c_binops_2},
! {"cfmvr64h", 0xee100530, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfmval32", 0xee100610, 8, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmv32al", 0xee000610, 8, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmvam32", 0xee100630, 8, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmv32am", 0xee000630, 8, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmvah32", 0xee100650, 8, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmv32ah", 0xee000650, 8, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmv32a", 0xee000670, 7, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmva32", 0xee100670, 7, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmv64a", 0xee000690, 7, ARM_EXT_MAVERICK, do_c_binops_3},
! {"cfmva64", 0xee100690, 7, ARM_EXT_MAVERICK, do_c_binops_3},
{"cfmvsc32", 0xee1006b0, 8, ARM_EXT_MAVERICK, do_c_dspsc_1},
{"cfmv32sc", 0xee0006b0, 8, ARM_EXT_MAVERICK, do_c_dspsc_2},
! {"cfcpys", 0xee000400, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcpyd", 0xee000420, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvtsd", 0xee000460, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvtds", 0xee000440, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvt32s", 0xee000480, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvt32d", 0xee0004a0, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvt64s", 0xee0004c0, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvt64d", 0xee0004e0, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvts32", 0xee100580, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfcvtd32", 0xee1005a0, 8, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cftruncs32", 0xee1005c0, 10, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cftruncd32", 0xee1005e0, 10, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfrshl32", 0xee000550, 8, ARM_EXT_MAVERICK, do_c_triple_4},
! {"cfrshl64", 0xee000570, 8, ARM_EXT_MAVERICK, do_c_triple_4},
{"cfsh32", 0xee000500, 6, ARM_EXT_MAVERICK, do_c_shift_1},
{"cfsh64", 0xee200500, 6, ARM_EXT_MAVERICK, do_c_shift_2},
! {"cfcmps", 0xee100490, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfcmpd", 0xee1004b0, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfcmp32", 0xee100590, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfcmp64", 0xee1005b0, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfabss", 0xee300400, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfabsd", 0xee300420, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfnegs", 0xee300440, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfnegd", 0xee300460, 6, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfadds", 0xee300480, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfaddd", 0xee3004a0, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfsubs", 0xee3004c0, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfsubd", 0xee3004e0, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmuls", 0xee100400, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmuld", 0xee100420, 6, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfabs32", 0xee300500, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfabs64", 0xee300520, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfneg32", 0xee300540, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfneg64", 0xee300560, 7, ARM_EXT_MAVERICK, do_c_binops_1},
! {"cfadd32", 0xee300580, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfadd64", 0xee3005a0, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfsub32", 0xee3005c0, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfsub64", 0xee3005e0, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmul32", 0xee100500, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmul64", 0xee100520, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmac32", 0xee100540, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmsc32", 0xee100560, 7, ARM_EXT_MAVERICK, do_c_triple_5},
! {"cfmadd32", 0xee000600, 8, ARM_EXT_MAVERICK, do_c_quad_6},
! {"cfmsub32", 0xee100600, 8, ARM_EXT_MAVERICK, do_c_quad_6},
! {"cfmadda32", 0xee200600, 9, ARM_EXT_MAVERICK, do_c_quad_6},
! {"cfmsuba32", 0xee300600, 9, ARM_EXT_MAVERICK, do_c_quad_6},
};
/* Defines for various bits that we will want to toggle. */
--- 1491,1564 ----
{"cfstrd", 0xec400400, 6, ARM_EXT_MAVERICK, do_c_ldst_2},
{"cfstr32", 0xec000500, 7, ARM_EXT_MAVERICK, do_c_ldst_3},
{"cfstr64", 0xec400500, 7, ARM_EXT_MAVERICK, do_c_ldst_4},
! {"cfmvsr", 0xee000450, 6, ARM_EXT_MAVERICK, do_c_binops_2a},
! {"cfmvrs", 0xee100450, 6, ARM_EXT_MAVERICK, do_c_binops_1a},
! {"cfmvdlr", 0xee000410, 7, ARM_EXT_MAVERICK, do_c_binops_2b},
! {"cfmvrdl", 0xee100410, 7, ARM_EXT_MAVERICK, do_c_binops_1b},
! {"cfmvdhr", 0xee000430, 7, ARM_EXT_MAVERICK, do_c_binops_2b},
! {"cfmvrdh", 0xee100430, 7, ARM_EXT_MAVERICK, do_c_binops_1b},
! {"cfmv64lr", 0xee000510, 8, ARM_EXT_MAVERICK, do_c_binops_2c},
! {"cfmvr64l", 0xee100510, 8, ARM_EXT_MAVERICK, do_c_binops_1c},
! {"cfmv64hr", 0xee000530, 8, ARM_EXT_MAVERICK, do_c_binops_2c},
! {"cfmvr64h", 0xee100530, 8, ARM_EXT_MAVERICK, do_c_binops_1c},
! {"cfmval32", 0xee100610, 8, ARM_EXT_MAVERICK, do_c_binops_3a},
! {"cfmv32al", 0xee000610, 8, ARM_EXT_MAVERICK, do_c_binops_3b},
! {"cfmvam32", 0xee100630, 8, ARM_EXT_MAVERICK, do_c_binops_3a},
! {"cfmv32am", 0xee000630, 8, ARM_EXT_MAVERICK, do_c_binops_3b},
! {"cfmvah32", 0xee100650, 8, ARM_EXT_MAVERICK, do_c_binops_3a},
! {"cfmv32ah", 0xee000650, 8, ARM_EXT_MAVERICK, do_c_binops_3b},
! {"cfmva32", 0xee100670, 7, ARM_EXT_MAVERICK, do_c_binops_3a},
! {"cfmv32a", 0xee000670, 7, ARM_EXT_MAVERICK, do_c_binops_3b},
! {"cfmva64", 0xee100690, 7, ARM_EXT_MAVERICK, do_c_binops_3c},
! {"cfmv64a", 0xee000690, 7, ARM_EXT_MAVERICK, do_c_binops_3d},
{"cfmvsc32", 0xee1006b0, 8, ARM_EXT_MAVERICK, do_c_dspsc_1},
{"cfmv32sc", 0xee0006b0, 8, ARM_EXT_MAVERICK, do_c_dspsc_2},
! {"cfcpys", 0xee000400, 6, ARM_EXT_MAVERICK, do_c_binops_1d},
! {"cfcpyd", 0xee000420, 6, ARM_EXT_MAVERICK, do_c_binops_1e},
! {"cfcvtsd", 0xee000460, 7, ARM_EXT_MAVERICK, do_c_binops_1f},
! {"cfcvtds", 0xee000440, 7, ARM_EXT_MAVERICK, do_c_binops_1g},
! {"cfcvt32s", 0xee000480, 8, ARM_EXT_MAVERICK, do_c_binops_1h},
! {"cfcvt32d", 0xee0004a0, 8, ARM_EXT_MAVERICK, do_c_binops_1i},
! {"cfcvt64s", 0xee0004c0, 8, ARM_EXT_MAVERICK, do_c_binops_1j},
! {"cfcvt64d", 0xee0004e0, 8, ARM_EXT_MAVERICK, do_c_binops_1k},
! {"cfcvts32", 0xee100580, 8, ARM_EXT_MAVERICK, do_c_binops_1l},
! {"cfcvtd32", 0xee1005a0, 8, ARM_EXT_MAVERICK, do_c_binops_1m},
! {"cftruncs32", 0xee1005c0, 10, ARM_EXT_MAVERICK, do_c_binops_1l},
! {"cftruncd32", 0xee1005e0, 10, ARM_EXT_MAVERICK, do_c_binops_1m},
! {"cfrshl32", 0xee000550, 8, ARM_EXT_MAVERICK, do_c_triple_4a},
! {"cfrshl64", 0xee000570, 8, ARM_EXT_MAVERICK, do_c_triple_4b},
{"cfsh32", 0xee000500, 6, ARM_EXT_MAVERICK, do_c_shift_1},
{"cfsh64", 0xee200500, 6, ARM_EXT_MAVERICK, do_c_shift_2},
! {"cfcmps", 0xee100490, 6, ARM_EXT_MAVERICK, do_c_triple_5a},
! {"cfcmpd", 0xee1004b0, 6, ARM_EXT_MAVERICK, do_c_triple_5b},
! {"cfcmp32", 0xee100590, 7, ARM_EXT_MAVERICK, do_c_triple_5c},
! {"cfcmp64", 0xee1005b0, 7, ARM_EXT_MAVERICK, do_c_triple_5d},
! {"cfabss", 0xee300400, 6, ARM_EXT_MAVERICK, do_c_binops_1d},
! {"cfabsd", 0xee300420, 6, ARM_EXT_MAVERICK, do_c_binops_1e},
! {"cfnegs", 0xee300440, 6, ARM_EXT_MAVERICK, do_c_binops_1d},
! {"cfnegd", 0xee300460, 6, ARM_EXT_MAVERICK, do_c_binops_1e},
! {"cfadds", 0xee300480, 6, ARM_EXT_MAVERICK, do_c_triple_5e},
! {"cfaddd", 0xee3004a0, 6, ARM_EXT_MAVERICK, do_c_triple_5f},
! {"cfsubs", 0xee3004c0, 6, ARM_EXT_MAVERICK, do_c_triple_5e},
! {"cfsubd", 0xee3004e0, 6, ARM_EXT_MAVERICK, do_c_triple_5f},
! {"cfmuls", 0xee100400, 6, ARM_EXT_MAVERICK, do_c_triple_5e},
! {"cfmuld", 0xee100420, 6, ARM_EXT_MAVERICK, do_c_triple_5f},
! {"cfabs32", 0xee300500, 7, ARM_EXT_MAVERICK, do_c_binops_1n},
! {"cfabs64", 0xee300520, 7, ARM_EXT_MAVERICK, do_c_binops_1o},
! {"cfneg32", 0xee300540, 7, ARM_EXT_MAVERICK, do_c_binops_1n},
! {"cfneg64", 0xee300560, 7, ARM_EXT_MAVERICK, do_c_binops_1o},
! {"cfadd32", 0xee300580, 7, ARM_EXT_MAVERICK, do_c_triple_5g},
! {"cfadd64", 0xee3005a0, 7, ARM_EXT_MAVERICK, do_c_triple_5h},
! {"cfsub32", 0xee3005c0, 7, ARM_EXT_MAVERICK, do_c_triple_5g},
! {"cfsub64", 0xee3005e0, 7, ARM_EXT_MAVERICK, do_c_triple_5h},
! {"cfmul32", 0xee100500, 7, ARM_EXT_MAVERICK, do_c_triple_5g},
! {"cfmul64", 0xee100520, 7, ARM_EXT_MAVERICK, do_c_triple_5h},
! {"cfmac32", 0xee100540, 7, ARM_EXT_MAVERICK, do_c_triple_5g},
! {"cfmsc32", 0xee100560, 7, ARM_EXT_MAVERICK, do_c_triple_5g},
! {"cfmadd32", 0xee000600, 8, ARM_EXT_MAVERICK, do_c_quad_6a},
! {"cfmsub32", 0xee100600, 8, ARM_EXT_MAVERICK, do_c_quad_6a},
! {"cfmadda32", 0xee200600, 9, ARM_EXT_MAVERICK, do_c_quad_6b},
! {"cfmsuba32", 0xee300600, 9, ARM_EXT_MAVERICK, do_c_quad_6b},
};
/* Defines for various bits that we will want to toggle. */
*************** static const struct thumb_opcode tinsns[
*** 1608,1692 ****
{"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
};
- struct reg_entry
- {
- const char * name;
- int number;
- };
-
- #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
- #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
- #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
-
- #define ARM_EXT_MAVERICKSC_REG 134
-
- #define cirrus_register(reg) ((reg) >= 50 && (reg) <= 134)
- #define cirrus_mvf_register(reg) ((reg) >= 50 && (reg) <= 65)
- #define cirrus_mvd_register(reg) ((reg) >= 70 && (reg) <= 85)
- #define cirrus_mvfx_register(reg) ((reg) >= 90 && (reg) <= 105)
- #define cirrus_mvdx_register(reg) ((reg) >= 110 && (reg) <= 125)
- #define cirrus_mvax_register(reg) ((reg) >= 130 && (reg) <= 133)
- #define ARM_EXT_MAVERICKsc_register(reg) ((reg) == ARM_EXT_MAVERICKSC_REG)
-
- #define REG_SP 13
- #define REG_LR 14
- #define REG_PC 15
-
- /* These are the standard names. Users can add aliases with .req. */
- static const struct reg_entry reg_table[] =
- {
- /* Processor Register Numbers. */
- {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
- {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
- {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
- {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
- /* APCS conventions. */
- {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
- {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
- {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
- {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
- /* ATPCS additions to APCS conventions. */
- {"wr", 7}, {"v8", 11},
- /* FP Registers. */
- {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
- {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
- {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
- {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
- {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
- {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
- {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
- {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
- {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
- {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
- /* ATPCS additions to float register names. */
- {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
- {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
- {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
- {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
- /* Cirrus DSP coprocessor registers. */
- {"mvf0", 50}, {"mvf1", 51}, {"mvf2", 52}, {"mvf3", 53},
- {"mvf4", 54}, {"mvf5", 55}, {"mvf6", 56}, {"mvf7", 57},
- {"mvf8", 58}, {"mvf9", 59}, {"mvf10", 60}, {"mvf11", 61},
- {"mvf12", 62},{"mvf13", 63}, {"mvf14", 64}, {"mvf15", 65},
- {"mvd0", 70}, {"mvd1", 71}, {"mvd2", 72}, {"mvd3", 73},
- {"mvd4", 74}, {"mvd5", 75}, {"mvd6", 76}, {"mvd7", 77},
- {"mvd8", 78}, {"mvd9", 79}, {"mvd10", 80}, {"mvd11", 81},
- {"mvd12", 82},{"mvd13", 83}, {"mvd14", 84}, {"mvd15", 85},
- {"mvfx0", 90},{"mvfx1", 91}, {"mvfx2", 92}, {"mvfx3", 93},
- {"mvfx4", 94},{"mvfx5", 95}, {"mvfx6", 96}, {"mvfx7", 97},
- {"mvfx8", 98},{"mvfx9", 99}, {"mvfx10", 100},{"mvfx11", 101},
- {"mvfx12", 102},{"mvfx13", 103},{"mvfx14", 104},{"mvfx15", 105},
- {"mvdx0", 110}, {"mvdx1", 111}, {"mvdx2", 112}, {"mvdx3", 113},
- {"mvdx4", 114}, {"mvdx5", 115}, {"mvdx6", 116}, {"mvdx7", 117},
- {"mvdx8", 118}, {"mvdx9", 119}, {"mvdx10", 120},{"mvdx11", 121},
- {"mvdx12", 122},{"mvdx13", 123},{"mvdx14", 124},{"mvdx15", 125},
- {"mvax0", 130}, {"mvax1", 131}, {"mvax2", 132}, {"mvax3", 133},
- {"dspsc", ARM_EXT_MAVERICKSC_REG},
- /* FIXME: At some point we need to add VFP register names. */
- /* Array terminator. */
- {NULL, 0}
- };
-
#define BAD_ARGS _("Bad arguments to instruction")
#define BAD_PC _("r15 not allowed here")
#define BAD_COND _("Instruction is not conditional")
--- 1787,1792 ----
*************** static struct hash_control * arm_ops_hsh
*** 1696,1702 ****
static struct hash_control * arm_tops_hsh = NULL;
static struct hash_control * arm_cond_hsh = NULL;
static struct hash_control * arm_shift_hsh = NULL;
- static struct hash_control * arm_reg_hsh = NULL;
static struct hash_control * arm_psr_hsh = NULL;
/* This table describes all the machine specific pseudo-ops the assembler
--- 1796,1801 ----
*************** reg_required_here (str, shift)
*** 2364,2370 ****
int reg;
char * start = * str;
! if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
{
if (shift >= 0)
inst.instruction |= reg << shift;
--- 2463,2469 ----
int reg;
char * start = * str;
! if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
{
if (shift >= 0)
inst.instruction |= reg << shift;
*************** psr_required_here (str)
*** 2457,2492 ****
static int
co_proc_number (str)
! char ** str;
{
int processor, pchar;
! skip_whitespace (* str);
/* The data sheet seems to imply that just a number on its own is valid
here, but the RISC iX assembler seems to accept a prefix 'p'. We will
accept either. */
! if (**str == 'p' || **str == 'P')
! (*str)++;
!
! pchar = *(*str)++;
! if (pchar >= '0' && pchar <= '9')
{
! processor = pchar - '0';
! if (**str >= '0' && **str <= '9')
{
! processor = processor * 10 + *(*str)++ - '0';
! if (processor > 15)
{
! inst.error = _("Illegal co-processor number");
! return FAIL;
}
}
! }
! else
! {
! inst.error = _("Bad or missing co-processor number");
! return FAIL;
}
inst.instruction |= processor << 8;
--- 2556,2596 ----
static int
co_proc_number (str)
! char **str;
{
int processor, pchar;
+ char *start;
! skip_whitespace (*str);
! start = *str;
/* The data sheet seems to imply that just a number on its own is valid
here, but the RISC iX assembler seems to accept a prefix 'p'. We will
accept either. */
! if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
! == FAIL)
{
! *str = start;
!
! pchar = *(*str)++;
! if (pchar >= '0' && pchar <= '9')
{
! processor = pchar - '0';
! if (**str >= '0' && **str <= '9')
{
! processor = processor * 10 + *(*str)++ - '0';
! if (processor > 15)
! {
! inst.error = _("Illegal co-processor number");
! return FAIL;
! }
}
}
! else
! {
! inst.error = _("Bad or missing co-processor number");
! return FAIL;
! }
}
inst.instruction |= processor << 8;
*************** cp_reg_required_here (str, where)
*** 2531,2539 ****
int reg;
char * start = *str;
! if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
{
- reg &= 15;
inst.instruction |= reg << where;
return reg;
}
--- 2635,2642 ----
int reg;
char * start = *str;
! if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
{
inst.instruction |= reg << where;
return reg;
}
*************** fp_reg_required_here (str, where)
*** 2555,2563 ****
int reg;
char * start = * str;
! if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
{
- reg &= 7;
inst.instruction |= reg << where;
return reg;
}
--- 2658,2665 ----
int reg;
char * start = * str;
! if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
{
inst.instruction |= reg << where;
return reg;
}
*************** thumb_load_store (str, load_store, size)
*** 6563,6617 ****
end_of_line (str);
}
- /* Given a register and a register type, return 1 if
- the register is of the given type, else return 0. */
-
- static int
- cirrus_valid_reg (reg, regtype)
- int reg;
- enum cirrus_regtype regtype;
- {
- switch (regtype)
- {
- case CIRRUS_REGTYPE_ANY:
- return 1;
-
- case CIRRUS_REGTYPE_MVF:
- return cirrus_mvf_register (reg);
-
- case CIRRUS_REGTYPE_MVFX:
- return cirrus_mvfx_register (reg);
-
- case CIRRUS_REGTYPE_MVD:
- return cirrus_mvd_register (reg);
-
- case CIRRUS_REGTYPE_MVDX:
- return cirrus_mvdx_register (reg);
-
- case CIRRUS_REGTYPE_MVAX:
- return cirrus_mvax_register (reg);
-
- case CIRRUS_REGTYPE_DSPSC:
- return ARM_EXT_MAVERICKsc_register (reg);
- }
-
- return 0;
- }
-
/* A register must be given at this point.
- If the register is a Cirrus register, convert it's reg# appropriately.
-
Shift is the place to put it in inst.instruction.
- regtype is type register type expected, and is:
- CIRRUS_REGTYPE_MVF
- CIRRUS_REGTYPE_MVFX
- CIRRUS_REGTYPE_MVD
- CIRRUS_REGTYPE_MVDX
- CIRRUS_REGTYPE_MVAX
- CIRRUS_REGTYPE_DSPSC
-
Restores input start point on err.
Returns the reg#, or FAIL. */
--- 6665,6674 ----
*************** static int
*** 6619,6672 ****
cirrus_reg_required_here (str, shift, regtype)
char ** str;
int shift;
! enum cirrus_regtype regtype;
{
! static char buff [135]; /* XXX */
! int reg;
! char * start = * str;
!
! if ((reg = arm_reg_parse (str)) != FAIL
! && (int_register (reg)
! || cirrus_register (reg)))
! {
! int orig_reg = reg;
!
! /* Calculate actual register # for opcode. */
! if (cirrus_register (reg)
! && !ARM_EXT_MAVERICKsc_register (reg)) /* Leave this one as is. */
! {
! if (reg >= 130)
! reg -= 130;
! else if (reg >= 110)
! reg -= 110;
! else if (reg >= 90)
! reg -= 90;
! else if (reg >= 70)
! reg -= 70;
! else if (reg >= 50)
! reg -= 50;
! }
!
! if (!cirrus_valid_reg (orig_reg, regtype))
! {
! sprintf (buff, _("invalid register type at '%.100s'"), start);
! inst.error = buff;
! return FAIL;
! }
if (shift >= 0)
inst.instruction |= reg << shift;
! return orig_reg;
}
! /* Restore the start point, we may have got a reg of the wrong class. */
*str = start;
/* In the few cases where we might be able to accept something else
this error can be overridden. */
! sprintf (buff, _("Cirrus register expected, not '%.100s'"), start);
! inst.error = buff;
return FAIL;
}
--- 6676,6700 ----
cirrus_reg_required_here (str, shift, regtype)
char ** str;
int shift;
! enum arm_reg_type regtype;
{
! int reg;
! char *start = *str;
+ if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
+ {
if (shift >= 0)
inst.instruction |= reg << shift;
! return reg;
}
! /* Restore the start point. */
*str = start;
/* In the few cases where we might be able to accept something else
this error can be overridden. */
! inst.error = _(all_reg_maps[regtype].expected);
return FAIL;
}
*************** cirrus_reg_required_here (str, shift, re
*** 6675,6795 ****
/* Wrapper functions. */
static void
! do_c_binops_1 (str)
char * str;
{
! do_c_binops (str, CIRRUS_MODE1);
}
static void
! do_c_binops_2 (str)
char * str;
{
! do_c_binops (str, CIRRUS_MODE2);
}
static void
! do_c_binops_3 (str)
char * str;
{
! do_c_binops (str, CIRRUS_MODE3);
}
static void
! do_c_triple_4 (str)
char * str;
{
! do_c_triple (str, CIRRUS_MODE4);
}
static void
! do_c_triple_5 (str)
char * str;
{
! do_c_triple (str, CIRRUS_MODE5);
}
static void
! do_c_quad_6 (str)
char * str;
{
! do_c_quad (str, CIRRUS_MODE6);
}
static void
do_c_dspsc_1 (str)
char * str;
{
! do_c_dspsc (str, CIRRUS_MODE1);
}
static void
do_c_dspsc_2 (str)
char * str;
{
! do_c_dspsc (str, CIRRUS_MODE2);
}
static void
do_c_shift_1 (str)
char * str;
{
! do_c_shift (str, CIRRUS_MODE1);
}
static void
do_c_shift_2 (str)
char * str;
{
! do_c_shift (str, CIRRUS_MODE2);
}
static void
do_c_ldst_1 (str)
char * str;
{
! do_c_ldst (str, CIRRUS_MODE1);
}
static void
do_c_ldst_2 (str)
char * str;
{
! do_c_ldst (str, CIRRUS_MODE2);
}
static void
do_c_ldst_3 (str)
char * str;
{
! do_c_ldst (str, CIRRUS_MODE3);
}
static void
do_c_ldst_4 (str)
char * str;
{
! do_c_ldst (str, CIRRUS_MODE4);
}
/* Isnsn like "foo X,Y". */
static void
! do_c_binops (str, mode)
char * str;
int mode;
{
! int shift1, shift2;
! shift1 = mode & 0xff;
! shift2 = (mode >> 8) & 0xff;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, shift1, CIRRUS_REGTYPE_ANY) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift2, CIRRUS_REGTYPE_ANY) == FAIL)
{
if (!inst.error)
inst.error = BAD_ARGS;
--- 6703,7051 ----
/* Wrapper functions. */
+ static void
+ do_c_binops_1a (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
+ }
+
+ static void
+ do_c_binops_1b (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
+ }
+
+ static void
+ do_c_binops_1c (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
+ }
+
+ static void
+ do_c_binops_1d (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
+ }
+
+ static void
+ do_c_binops_1e (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
+ }
+
+ static void
+ do_c_binops_1f (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
+ }
+
+ static void
+ do_c_binops_1g (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
+ }
+
+ static void
+ do_c_binops_1h (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
+ }
+
+ static void
+ do_c_binops_1i (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
+ }
+
+ static void
+ do_c_binops_1j (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
+ }
+
+ static void
+ do_c_binops_1k (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
+ }
+
+ static void
+ do_c_binops_1l (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
+ }
+
+ static void
+ do_c_binops_1m (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
+ }
+
+ static void
+ do_c_binops_1n (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
+ }
+
+ static void
+ do_c_binops_1o (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
+ }
+
+ static void
+ do_c_binops_2a (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
+ }
+
+ static void
+ do_c_binops_2b (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
+ }
+
+ static void
+ do_c_binops_2c (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
+ }
+
+ static void
+ do_c_binops_3a (str)
+ char * str;
+ {
+ do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
+ }
+
static void
! do_c_binops_3b (str)
char * str;
{
! do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
}
static void
! do_c_binops_3c (str)
char * str;
{
! do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
}
static void
! do_c_binops_3d (str)
char * str;
{
! do_c_binops (str, CIRRUS_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
}
static void
! do_c_triple_4a (str)
char * str;
{
! do_c_triple (str, CIRRUS_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
}
static void
! do_c_triple_4b (str)
char * str;
{
! do_c_triple (str, CIRRUS_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
}
static void
! do_c_triple_5a (str)
char * str;
{
! do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
}
static void
+ do_c_triple_5b (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
+ }
+
+ static void
+ do_c_triple_5c (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
+ }
+
+ static void
+ do_c_triple_5d (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
+ }
+
+ static void
+ do_c_triple_5e (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
+ }
+
+ static void
+ do_c_triple_5f (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
+ }
+
+ static void
+ do_c_triple_5g (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
+ }
+
+ static void
+ do_c_triple_5h (str)
+ char * str;
+ {
+ do_c_triple (str, CIRRUS_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
+ }
+
+ static void
+ do_c_quad_6a (str)
+ char * str;
+ {
+ do_c_quad (str, CIRRUS_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
+ REG_TYPE_MVFX);
+ }
+
+ static void
+ do_c_quad_6b (str)
+ char * str;
+ {
+ do_c_quad (str, CIRRUS_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
+ REG_TYPE_MVFX);
+ }
+
+ /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
+ static void
do_c_dspsc_1 (str)
char * str;
{
! skip_whitespace (str);
!
! /* cfmvsc32. */
! if (cirrus_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
! || skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
! {
! if (!inst.error)
! inst.error = BAD_ARGS;
!
! return;
! }
!
! end_of_line (str);
}
+ /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
static void
do_c_dspsc_2 (str)
char * str;
{
! skip_whitespace (str);
!
! /* cfmv32sc. */
! if (cirrus_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
! || skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
! {
! if (!inst.error)
! inst.error = BAD_ARGS;
!
! return;
! }
!
! end_of_line (str);
}
static void
do_c_shift_1 (str)
char * str;
{
! do_c_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
}
static void
do_c_shift_2 (str)
char * str;
{
! do_c_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
}
static void
do_c_ldst_1 (str)
char * str;
{
! do_c_ldst (str, REG_TYPE_MVF);
}
static void
do_c_ldst_2 (str)
char * str;
{
! do_c_ldst (str, REG_TYPE_MVD);
}
static void
do_c_ldst_3 (str)
char * str;
{
! do_c_ldst (str, REG_TYPE_MVFX);
}
static void
do_c_ldst_4 (str)
char * str;
{
! do_c_ldst (str, REG_TYPE_MVDX);
}
/* Isnsn like "foo X,Y". */
static void
! do_c_binops (str, mode, reg0, reg1)
char * str;
int mode;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
{
! int shift0, shift1;
! shift0 = mode & 0xff;
! shift1 = (mode >> 8) & 0xff;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, shift0, reg0) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift1, reg1) == FAIL)
{
if (!inst.error)
inst.error = BAD_ARGS;
*************** do_c_binops (str, mode)
*** 6801,6823 ****
/* Isnsn like "foo X,Y,Z". */
static void
! do_c_triple (str, mode)
char * str;
int mode;
{
! int shift1, shift2, shift3;
! shift1 = mode & 0xff;
! shift2 = (mode >> 8) & 0xff;
! shift3 = (mode >> 16) & 0xff;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, shift1, CIRRUS_REGTYPE_ANY) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift2, CIRRUS_REGTYPE_ANY) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift3, CIRRUS_REGTYPE_ANY) == FAIL)
{
if (!inst.error)
inst.error = BAD_ARGS;
--- 7057,7082 ----
/* Isnsn like "foo X,Y,Z". */
static void
! do_c_triple (str, mode, reg0, reg1, reg2)
char * str;
int mode;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
+ enum arm_reg_type reg2;
{
! int shift0, shift1, shift2;
! shift0 = mode & 0xff;
! shift1 = (mode >> 8) & 0xff;
! shift2 = (mode >> 16) & 0xff;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, shift0, reg0) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift1, reg1) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift2, reg2) == FAIL)
{
if (!inst.error)
inst.error = BAD_ARGS;
*************** do_c_triple (str, mode)
*** 6830,6860 ****
where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
static void
! do_c_quad (str, mode)
char * str;
int mode;
{
! int shift1, shift2, shift3, shift4;
! enum cirrus_regtype rt;
!
! rt = (inst.instruction << 4 == 0xe2006000
! || inst.instruction << 4 == 0xe3006000) ? CIRRUS_REGTYPE_MVAX
! : CIRRUS_REGTYPE_MVFX;
! shift1 = mode & 0xff;
! shift2 = (mode >> 8) & 0xff;
! shift3 = (mode >> 16) & 0xff;
! shift4 = (mode >> 24) & 0xff;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, shift1, CIRRUS_REGTYPE_MVAX) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift2, rt) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift3, CIRRUS_REGTYPE_MVFX) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift4, CIRRUS_REGTYPE_MVFX) == FAIL)
{
if (!inst.error)
inst.error = BAD_ARGS;
--- 7089,7118 ----
where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
static void
! do_c_quad (str, mode, reg0, reg1, reg2, reg3)
char * str;
int mode;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
+ enum arm_reg_type reg2;
+ enum arm_reg_type reg3;
{
! int shift0, shift1, shift2, shift3;
! shift0= mode & 0xff;
! shift1 = (mode >> 8) & 0xff;
! shift2 = (mode >> 16) & 0xff;
! shift3 = (mode >> 24) & 0xff;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, shift0, reg0) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift1, reg1) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift2, reg2) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, shift3, reg3) == FAIL)
{
if (!inst.error)
inst.error = BAD_ARGS;
*************** do_c_quad (str, mode)
*** 6863,6918 ****
end_of_line (str);
}
- /* cfmvsc32<cond> DSPSC,MVFX[15:0].
- cfmv32sc<cond> MVFX[15:0],DSPSC. */
-
- static void
- do_c_dspsc (str, mode)
- char * str;
- int mode;
- {
- int error;
-
- skip_whitespace (str);
-
- error = 0;
-
- if (mode == CIRRUS_MODE1)
- {
- /* cfmvsc32. */
- if (cirrus_reg_required_here (&str, -1, CIRRUS_REGTYPE_DSPSC) == FAIL
- || skip_past_comma (&str) == FAIL
- || cirrus_reg_required_here (&str, 16, CIRRUS_REGTYPE_MVFX) == FAIL)
- error = 1;
- }
- else
- {
- /* cfmv32sc. */
- if (cirrus_reg_required_here (&str, 0, CIRRUS_REGTYPE_MVFX) == FAIL
- || skip_past_comma (&str) == FAIL
- || cirrus_reg_required_here (&str, -1, CIRRUS_REGTYPE_DSPSC) == FAIL)
- error = 1;
- }
-
- if (error)
- {
- if (!inst.error)
- inst.error = BAD_ARGS;
- }
- else
- {
- end_of_line (str);
- }
- }
-
/* Cirrus shift immediate instructions.
cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
static void
! do_c_shift (str, mode)
char * str;
! int mode;
{
int error;
int imm, neg = 0;
--- 7121,7135 ----
end_of_line (str);
}
/* Cirrus shift immediate instructions.
cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
static void
! do_c_shift (str, reg0, reg1)
char * str;
! enum arm_reg_type reg0;
! enum arm_reg_type reg1;
{
int error;
int imm, neg = 0;
*************** do_c_shift (str, mode)
*** 6921,6935 ****
error = 0;
! if (cirrus_reg_required_here (&str, 12,
! (mode == CIRRUS_MODE1)
! ? CIRRUS_REGTYPE_MVFX
! : CIRRUS_REGTYPE_MVDX) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, 16,
! (mode == CIRRUS_MODE1)
! ? CIRRUS_REGTYPE_MVFX
! : CIRRUS_REGTYPE_MVDX) == FAIL
|| skip_past_comma (&str) == FAIL)
{
if (!inst.error)
--- 7138,7146 ----
error = 0;
! if (cirrus_reg_required_here (&str, 12, reg0) == FAIL
|| skip_past_comma (&str) == FAIL
! || cirrus_reg_required_here (&str, 16, reg1) == FAIL
|| skip_past_comma (&str) == FAIL)
{
if (!inst.error)
*************** cirrus_parse_offset (str, negative)
*** 7027,7053 ****
<insn><cond> CRd,[Rn],<offset>. */
static void
! do_c_ldst (str, mode)
char * str;
! int mode;
{
int offset, negative;
- enum cirrus_regtype rt;
- rt = mode == CIRRUS_MODE1 ? CIRRUS_REGTYPE_MVF
- : mode == CIRRUS_MODE2 ? CIRRUS_REGTYPE_MVD
- : mode == CIRRUS_MODE3 ? CIRRUS_REGTYPE_MVFX
- : mode == CIRRUS_MODE4 ? CIRRUS_REGTYPE_MVDX : CIRRUS_REGTYPE_MVF;
-
skip_whitespace (str);
! if (cirrus_reg_required_here (& str, 12, rt) == FAIL
! || skip_past_comma (& str) == FAIL
|| *str++ != '['
! || reg_required_here (& str, 16) == FAIL)
goto fail_ldst;
! if (skip_past_comma (& str) == SUCCESS)
{
/* You are here: "<offset>]{!}". */
inst.instruction |= PRE_INDEX;
--- 7238,7258 ----
<insn><cond> CRd,[Rn],<offset>. */
static void
! do_c_ldst (str, reg0)
char * str;
! enum arm_reg_type reg0;
{
int offset, negative;
skip_whitespace (str);
! if (cirrus_reg_required_here (&str, 12, reg0) == FAIL
! || skip_past_comma (&str) == FAIL
|| *str++ != '['
! || reg_required_here (&str, 16) == FAIL)
goto fail_ldst;
! if (skip_past_comma (&str) == SUCCESS)
{
/* You are here: "<offset>]{!}". */
inst.instruction |= PRE_INDEX;
*************** do_t_adr (str)
*** 7513,7522 ****
}
static void
! insert_reg (entry)
! int entry;
{
! int len = strlen (reg_table[entry].name) + 2;
char * buf = (char *) xmalloc (len);
char * buf2 = (char *) xmalloc (len);
int i = 0;
--- 7718,7728 ----
}
static void
! insert_reg (r, htab)
! const struct reg_entry *r;
! struct hash_control *htab;
{
! int len = strlen (r->name) + 2;
char * buf = (char *) xmalloc (len);
char * buf2 = (char *) xmalloc (len);
int i = 0;
*************** insert_reg (entry)
*** 7525,7545 ****
buf[i++] = REGISTER_PREFIX;
#endif
! strcpy (buf + i, reg_table[entry].name);
for (i = 0; buf[i]; i++)
buf2[i] = TOUPPER (buf[i]);
buf2[i] = '\0';
! hash_insert (arm_reg_hsh, buf, (PTR) & reg_table[entry]);
! hash_insert (arm_reg_hsh, buf2, (PTR) & reg_table[entry]);
}
static void
! insert_reg_alias (str, regnum)
char *str;
int regnum;
{
struct reg_entry *new =
(struct reg_entry *) xmalloc (sizeof (struct reg_entry));
--- 7731,7765 ----
buf[i++] = REGISTER_PREFIX;
#endif
! strcpy (buf + i, r->name);
for (i = 0; buf[i]; i++)
buf2[i] = TOUPPER (buf[i]);
buf2[i] = '\0';
! hash_insert (htab, buf, (PTR) r);
! hash_insert (htab, buf2, (PTR) r);
}
static void
! build_reg_hsh (map)
! struct reg_map *map;
! {
! const struct reg_entry *r;
!
! if ((map->htab = hash_new ()) == NULL)
! as_fatal (_("Virtual memory exhausted"));
!
! for (r = map->names; r->name != NULL; r++)
! insert_reg (r, map->htab);
! }
!
! static void
! insert_reg_alias (str, regnum, htab)
char *str;
int regnum;
+ struct hash_control *htab;
{
struct reg_entry *new =
(struct reg_entry *) xmalloc (sizeof (struct reg_entry));
*************** insert_reg_alias (str, regnum)
*** 7549,7557 ****
new->name = name;
new->number = regnum;
! hash_insert (arm_reg_hsh, name, (PTR) new);
}
static void
set_constant_flonums ()
{
--- 7769,7863 ----
new->name = name;
new->number = regnum;
! hash_insert (htab, name, (PTR) new);
}
+ /* Look for the .req directive. This is of the form:
+
+ newname .req existing_name
+
+ If we find one, or if it looks sufficiently like one that we want to
+ handle any error here, return non-zero. Otherwise return zero. */
+ static int
+ create_register_alias (newname, p)
+ char *newname;
+ char *p;
+ {
+ char *q;
+ char c;
+
+ q = p;
+ skip_whitespace (q);
+
+ c = *p;
+ *p = '\0';
+
+ if (*q && !strncmp (q, ".req ", 5))
+ {
+ char *copy_of_str;
+ char *r;
+
+ #ifdef IGNORE_OPCODE_CASE
+ newname = original_case_string;
+ #endif
+ copy_of_str = newname;
+
+ q += 4;
+ skip_whitespace (q);
+
+ for (r = q; *r != '\0'; r++)
+ if (*r == ' ')
+ break;
+
+ if (r != q)
+ {
+ enum arm_reg_type new_type, old_type;
+ int old_regno;
+ char d = *r;
+
+ *r = '\0';
+ old_type = arm_reg_parse_any (q);
+ *r = d;
+
+ new_type = arm_reg_parse_any (newname);
+
+ if (new_type == REG_TYPE_MAX)
+ {
+ if (old_type != REG_TYPE_MAX)
+ {
+ old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
+ insert_reg_alias (newname, old_regno,
+ all_reg_maps[old_type].htab);
+ }
+ else
+ as_warn (_("register '%s' does not exist\n"), q);
+ }
+ else if (old_type == REG_TYPE_MAX)
+ {
+ as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
+ copy_of_str, q);
+ }
+ else
+ {
+ /* Do not warn about redefinitions to the same alias. */
+ if (new_type != old_type
+ || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
+ != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
+ as_warn (_("ignoring redefinition of register alias '%s'"),
+ copy_of_str);
+
+ }
+ }
+ else
+ as_warn (_("ignoring incomplete .req pseuso op"));
+
+ *p = c;
+ return 1;
+ }
+ *p = c;
+ return 0;
+ }
+
static void
set_constant_flonums ()
{
*************** build_arm_ops_hsh ()
*** 7574,7580 ****
for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
{
! CONST struct asm_opcode *insn = insns + i;
if (insn->cond_offset != 0)
{
--- 7880,7886 ----
for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
{
! const struct asm_opcode *insn = insns + i;
if (insn->cond_offset != 0)
{
*************** md_begin ()
*** 7620,7626 ****
|| (arm_tops_hsh = hash_new ()) == NULL
|| (arm_cond_hsh = hash_new ()) == NULL
|| (arm_shift_hsh = hash_new ()) == NULL
- || (arm_reg_hsh = hash_new ()) == NULL
|| (arm_psr_hsh = hash_new ()) == NULL)
as_fatal (_("Virtual memory exhausted"));
--- 7926,7931 ----
*************** md_begin ()
*** 7634,7641 ****
for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
! for (i = 0; reg_table[i].name; i++)
! insert_reg (i);
set_constant_flonums ();
--- 7939,7946 ----
for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
! for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
! build_reg_hsh (all_reg_maps + i);
set_constant_flonums ();
*************** md_undefined_symbol (name)
*** 7924,7931 ****
advance the pointer. */
static int
! arm_reg_parse (ccp)
register char ** ccp;
{
char * start = * ccp;
char c;
--- 8229,8237 ----
advance the pointer. */
static int
! arm_reg_parse (ccp, htab)
register char ** ccp;
+ struct hash_control *htab;
{
char * start = * ccp;
char c;
*************** arm_reg_parse (ccp)
*** 7951,7957 ****
c = *p++;
*--p = 0;
! reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
*p = c;
if (reg)
--- 8257,8263 ----
c = *p++;
*--p = 0;
! reg = (struct reg_entry *) hash_find (htab, start);
*p = c;
if (reg)
*************** arm_reg_parse (ccp)
*** 7963,7968 ****
--- 8269,8290 ----
return FAIL;
}
+ /* Search for the following register name in each of the possible reg name
+ tables. Return the classification if found, or REG_TYPE_MAX if not
+ present. */
+ static enum arm_reg_type
+ arm_reg_parse_any (cp)
+ char *cp;
+ {
+ int i;
+
+ for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
+ if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
+ return (enum arm_reg_type) i;
+
+ return REG_TYPE_MAX;
+ }
+
void
md_apply_fix3 (fixP, valP, seg)
fixS * fixP;
*************** void
*** 8774,8783 ****
md_assemble (str)
char * str;
{
! char c;
! char * p;
! char * q;
! char * start;
/* Align the instruction.
This may not be the right thing to do but ... */
--- 9096,9104 ----
md_assemble (str)
char * str;
{
! char c;
! char *p;
! char *start;
/* Align the instruction.
This may not be the right thing to do but ... */
*************** md_assemble (str)
*** 8842,8848 ****
c = *p;
*p = '\0';
! opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
*p = c;
if (opcode)
--- 9163,9169 ----
c = *p;
*p = '\0';
! opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
*p = c;
if (opcode)
*************** md_assemble (str)
*** 8864,8931 ****
/* It wasn't an instruction, but it might be a register alias of the form
alias .req reg. */
! q = p;
! skip_whitespace (q);
!
! c = *p;
! *p = '\0';
!
! if (*q && !strncmp (q, ".req ", 4))
! {
! int reg;
! char * copy_of_str;
! char * r;
!
! #ifdef IGNORE_OPCODE_CASE
! str = original_case_string;
! #endif
! copy_of_str = str;
!
! q += 4;
! skip_whitespace (q);
!
! for (r = q; *r != '\0'; r++)
! if (*r == ' ')
! break;
!
! if (r != q)
! {
! int regnum;
! char d = *r;
!
! *r = '\0';
! regnum = arm_reg_parse (& q);
! *r = d;
!
! reg = arm_reg_parse (& str);
!
! if (reg == FAIL)
! {
! if (regnum != FAIL)
! insert_reg_alias (str, regnum);
! else
! as_warn (_("register '%s' does not exist\n"), q);
! }
! else if (regnum != FAIL)
! {
! if (reg != regnum)
! as_warn (_("ignoring redefinition of register alias '%s'"),
! copy_of_str);
!
! /* Do not warn about redefinitions to the same alias. */
! }
! else
! as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
! copy_of_str, q);
! }
! else
! as_warn (_("ignoring incomplete .req pseuso op"));
!
! *p = c;
! return;
! }
- *p = c;
as_bad (_("bad instruction `%s'"), start);
}
--- 9185,9193 ----
/* It wasn't an instruction, but it might be a register alias of the form
alias .req reg. */
! if (create_register_alias (str, p))
! return;
as_bad (_("bad instruction `%s'"), start);
}