From 48c9f030c98a3b53b9cb962857ffc16c435a63db Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 7 Oct 2004 14:18:17 +0000 Subject: [PATCH] Add support for CRX co-processor opcodes --- gas/ChangeLog | 7 ++++ gas/config/tc-crx.c | 17 +++++++- gas/testsuite/ChangeLog | 10 +++++ gas/testsuite/gas/crx/cop_insn.d | 67 +++++++++++++++++++++++++++++ gas/testsuite/gas/crx/cop_insn.s | 77 ++++++++++++++++++++++++++++++++++ gas/testsuite/gas/crx/load_stor_insn.d | 7 ---- gas/testsuite/gas/crx/load_stor_insn.s | 8 ---- gas/testsuite/gas/crx/misc_insn.d | 55 +++++++----------------- gas/testsuite/gas/crx/misc_insn.s | 34 --------------- include/opcode/ChangeLog | 5 +++ include/opcode/crx.h | 7 ++-- opcodes/ChangeLog | 9 ++++ opcodes/crx-dis.c | 73 ++++++++++++++++++++++---------- opcodes/crx-opc.c | 56 ++++++++++++++++--------- 14 files changed, 295 insertions(+), 137 deletions(-) create mode 100644 gas/testsuite/gas/crx/cop_insn.d create mode 100644 gas/testsuite/gas/crx/cop_insn.s diff --git a/gas/ChangeLog b/gas/ChangeLog index dbd128a..e9911f6 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2004-10-07 Tomer Levi + + * config/tc-crx.c (preprocess_reglist): Handle Co-processor + Special registers. + (get_cinv_parameters): Add 'b' option to invalidate the + branch-target cache. + 2004-10-05 Paul Brook * config/tc-arm.c (unwind): New variable. diff --git a/gas/config/tc-crx.c b/gas/config/tc-crx.c index 382c562..6c144b3 100644 --- a/gas/config/tc-crx.c +++ b/gas/config/tc-crx.c @@ -1724,7 +1724,7 @@ static int get_cinv_parameters (char * operand) { char *p = operand; - int d_used = 0, i_used = 0, u_used = 0; + int d_used = 0, i_used = 0, u_used = 0, b_used = 0; while (*++p != ']') { @@ -1737,11 +1737,14 @@ get_cinv_parameters (char * operand) i_used = 1; else if (*p == 'u') u_used = 1; + else if (*p == 'b') + b_used = 1; else as_bad (_("Illegal `cinv' parameter: `%c'"), *p); } - return ((d_used ? 4 : 0) + return ((b_used ? 8 : 0) + + (d_used ? 4 : 0) + (i_used ? 2 : 0) + (u_used ? 1 : 0)); } @@ -2374,12 +2377,22 @@ preprocess_reglist (char *param, int *allocated) strncpy (reg_name, regP, paramP - regP); + /* Coprocessor register c. */ if (IS_INSN_TYPE (COP_REG_INS)) { if ((cr = get_copregister (reg_name)) == nullcopregister) as_bad (_("Illegal register `%s' in cop-register list"), reg_name); mask_reg (getreg_image (cr - c0), &mask); } + /* Coprocessor Special register cs. */ + else if (IS_INSN_TYPE (COPS_REG_INS)) + { + if ((cr = get_copregister (reg_name)) == nullcopregister) + as_bad (_("Illegal register `%s' in cop-special-register list"), + reg_name); + mask_reg (getreg_image (cr - cs0), &mask); + } + /* General purpose register r. */ else { if ((r = get_register (reg_name)) == nullregister) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 7671424..565dc1b 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2004-10-07 Tomer Levi + + * gas/crx/cop_insn.s: New file. + * gas/crx/cop_insn.d: Likewise. + * gas/crx/load_stor_insn.s: Move Co-processor insns to a separate + test. + * gas/crx/misc_insn.s: Likewise. + * gas/crx/load_stor_insn.d: Regenerate. + * gas/crx/misc_insn.d: Likewise. + 2004-10-06 Aldy Hernandez * gas/ppc/e500.s: Add double-precision instructions. diff --git a/gas/testsuite/gas/crx/cop_insn.d b/gas/testsuite/gas/crx/cop_insn.d new file mode 100644 index 0000000..9108f1e --- /dev/null +++ b/gas/testsuite/gas/crx/cop_insn.d @@ -0,0 +1,67 @@ +#as: +#objdump: -dr +#name: cop_insn + +.*: +file format .* + +Disassembly of section .text: + +00000000 : + 0: 1f 30 1e 30 mtcr \$0xf, r1, c14 + +00000004 : + 4: 13 30 72 31 mfcr \$0x3, c7, r2 + +00000008 : + 8: 12 30 51 32 mtcsr \$0x2, r5, cs1 + +0000000c : + c: 11 30 ce 33 mfcsr \$0x1, cs12, r14 + +00000010 : + 10: 11 30 38 34 ldcr \$0x1, r3, c8 + +00000014 : + 14: 12 30 4b 35 stcr \$0x2, r4, c11 + +00000018 : + 18: 14 30 6c 36 ldcsr \$0x4, r6, cs12 + +0000001c : + 1c: 17 30 dd 37 stcsr \$0x7, r13, cs13 + +00000020 : + 20: 13 31 01 30 loadmcr \$0x3, r1, {c2,c3,c5} + 24: 2c 00 + +00000026 : + 26: 1f 31 1e 30 stormcr \$0xf, r14, {c4,c7,c9,c10} + 2a: 90 06 + +0000002c : + 2c: 1c 31 28 30 loadmcsr \$0xc, r8, {cs7,cs8,cs9,cs10,cs11} + 30: 80 0f + +00000032 : + 32: 19 31 39 30 stormcsr \$0x9, r9, {cs4,cs7,cs10} + 36: 90 04 + +00000038 : + 38: 13 30 48 77 bcop \$0x7, \$0x3, \*\+0x90 + 3c: 1c 31 fa 76 bcop \$0x6, \$0xc, \*\-0xbcdfe + 40: 01 19 + +00000042 : + 42: 13 30 45 b2 cpdop \$0x3, \$0x2, r4, r5 + 46: 17 31 12 ba cpdop \$0x7, \$0xa, r1, r2, \$0x1234 + 4a: 34 12 + +0000004c : + 4c: 09 30 10 00 mtpr r0, hi + +00000050 : + 50: 0a 30 05 11 mfpr lo, r5 + 54: 0a 30 0a 90 mfpr uhi, r10 + +00000058 : + 58: 10 30 0f 00 cinv \[b,d,i,u\] diff --git a/gas/testsuite/gas/crx/cop_insn.s b/gas/testsuite/gas/crx/cop_insn.s new file mode 100644 index 0000000..1415cff --- /dev/null +++ b/gas/testsuite/gas/crx/cop_insn.s @@ -0,0 +1,77 @@ +# Co-Processor instructions. + .data +foodata: .word 42 + .text +footext: + + .global mtcr +mtcr: +mtcr $0xf, r1, c14 + + .global mfcr +mfcr: +mfcr $3, c7, r2 + + .global mtcsr +mtcsr: +mtcsr $0x2, r5, cs1 + + .global mfcsr +mfcsr: +mfcsr $01, cs12, ra + + .global ldcr +ldcr: +ldcr $1, r3, c8 + + .global stcr +stcr: +stcr $2, r4, c11 + + .global ldcsr +ldcsr: +ldcsr $4, r6, cs12 + + .global stcsr +stcsr: +stcsr $7, r13, cs13 + + .global loadmcr +loadmcr: +loadmcr $3, r1, {c2,c3,c5} + + .global stormcr +stormcr: +stormcr $15, ra, {c10,c9,c7,c4} + + .global loadmcsr +loadmcsr: +loadmcsr $12, r8, {cs7, cs8, cs9, cs10, cs11} + + .global stormcsr +stormcsr: +stormcsr $9, r9, {cs10,cs7,cs4} + + .global bcop +bcop: +bcop $7, $3, 0x90 +bcop $6, $12, -0xbcdfe + + .global cpdop +cpdop: +cpdop $3, $2, r4, r5 +cpdop $7, $10, r1, r2, $0x1234 + + .global mtpr +mtpr: +mtpr r0 , hi + + .global mfpr +mfpr: +mfpr lo , r5 +mfpr uhi , r10 + + .global cinv +cinv: +cinv [i,d,u,b] + diff --git a/gas/testsuite/gas/crx/load_stor_insn.d b/gas/testsuite/gas/crx/load_stor_insn.d index 6a4a177..805e3ea 100644 --- a/gas/testsuite/gas/crx/load_stor_insn.d +++ b/gas/testsuite/gas/crx/load_stor_insn.d @@ -141,10 +141,3 @@ Disassembly of section .text: 182: af 36 05 a0 stord \$0xf, 0x5\(r10\)\+ 186: a0 36 e4 bf stord \$0x0, 0xfe4\(r11\)\+ -0000018a : - 18a: 13 31 01 30 loadmcr \$0x3, r1, {c2,c3,c5} - 18e: 2c 00 - -00000190 : - 190: 1f 31 1e 30 stormcr \$0xf, r14, {c4,c7,c9,c10} - 194: 90 06 diff --git a/gas/testsuite/gas/crx/load_stor_insn.s b/gas/testsuite/gas/crx/load_stor_insn.s index 6b71621..4c9fd41 100644 --- a/gas/testsuite/gas/crx/load_stor_insn.s +++ b/gas/testsuite/gas/crx/load_stor_insn.s @@ -108,11 +108,3 @@ stord r14, -0657(r15,r7,1) stord $0xf, 05(r10)+ stord $0x0, -034(r11)+ -# CO-processor registers - .global loadmcr -loadmcr: -loadmcr $3, r1, {c2,c3,c5} - - .global stormcr -stormcr: -stormcr $15, ra, {c10,c9,c7,c4} diff --git a/gas/testsuite/gas/crx/misc_insn.d b/gas/testsuite/gas/crx/misc_insn.d index c183222..ea4c7c4 100644 --- a/gas/testsuite/gas/crx/misc_insn.d +++ b/gas/testsuite/gas/crx/misc_insn.d @@ -1,6 +1,6 @@ #as: #objdump: -dr -#name: load_stor_insn +#name: misc_insn .*: +file format .* @@ -213,48 +213,21 @@ Disassembly of section .text: 0000010c : 10c: 08 30 2c ae cntlsd r2, r12 -00000110 : - 110: 09 30 10 00 mtpr r0, hi +00000110 : + 110: f8 ff excp bpt + 112: f5 ff excp svc -00000114 : - 114: 0a 30 05 11 mfpr lo, r5 - 118: 0a 30 0a 90 mfpr uhi, r10 +00000114 : + 114: 61 3e ec 21 ram \$0x18, \$0x9, \$0x1, r14, r12 -0000011c : - 11c: 1f 30 1e 30 mtcr \$0xf, r1, c14 +00000118 : + 118: fd 3e 21 ee rim \$0x1f, \$0xf, \$0xe, r2, r1 -00000120 : - 120: 13 30 72 31 mfcr \$0x3, c7, r2 +0000011c : + 11c: f1 fd rotb \$0x7, r1 -00000124 : - 124: 12 30 51 32 mtcsr \$0x2, r5, cs1 +0000011e : + 11e: d3 b9 rotw \$0xd, r3 -00000128 : - 128: 11 30 ce 33 mfcsr \$0x1, cs12, r14 - -0000012c : - 12c: 13 30 48 77 bcop \$0x7, \$0x3, \*\+0x90 - 130: 1c 31 fa 76 bcop \$0x6, \$0xc, \*\-0xbcdfe - 134: 01 19 - -00000136 : - 136: f8 ff excp bpt - 138: f5 ff excp svc - -0000013a : - 13a: 10 30 07 00 cinv \[d,i,u\] - -0000013e : - 13e: 61 3e ec 21 ram \$0x18, \$0x9, \$0x1, r14, r12 - -00000142 : - 142: fd 3e 21 ee rim \$0x1f, \$0xf, \$0xe, r2, r1 - -00000146 : - 146: f1 fd rotb \$0x7, r1 - -00000148 : - 148: d3 b9 rotw \$0xd, r3 - -0000014a : - 14a: 08 30 b2 f1 rotd \$0x1b, r2 +00000120 : + 120: 08 30 b2 f1 rotd \$0x1b, r2 diff --git a/gas/testsuite/gas/crx/misc_insn.s b/gas/testsuite/gas/crx/misc_insn.s index f6a2488..2330d4c 100644 --- a/gas/testsuite/gas/crx/misc_insn.s +++ b/gas/testsuite/gas/crx/misc_insn.s @@ -284,45 +284,11 @@ subqd r0 , r10 cntlsd: cntlsd r2 , r12 - .global mtpr -mtpr: -mtpr r0 , hi - - .global mfpr -mfpr: -mfpr lo , r5 -mfpr uhi , r10 - - .global mtcr -mtcr: -mtcr $0xf, r1, c14 - - .global mfcr -mfcr: -mfcr $3, c7, r2 - - .global mtcsr -mtcsr: -mtcsr $0x2, r5, cs1 - - .global mfcsr -mfcsr: -mfcsr $01, cs12, ra - - .global bcop -bcop: -bcop $7, $3, 0x90 -bcop $6, $12, -0xbcdfe - .global excp excp: excp BPT excp svc - .global cinv -cinv: -cinv [i,d,u] - .global ram ram: ram $24, $9, $1, ra, r12 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 6d75eee..4eb8348 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2004-10-07 Tomer Levi + + * crx.h: Add COPS_REG_INS - Coprocessor Special register + instruction type. + 2004-09-30 Paul Brook * arm.h (ARM_EXT_V6K, ARM_EXT_V6Z): Define. diff --git a/include/opcode/crx.h b/include/opcode/crx.h index 1e0d573..58db2f8 100644 --- a/include/opcode/crx.h +++ b/include/opcode/crx.h @@ -168,9 +168,10 @@ operand_type; #define DIV_INS 14 #define COP_BRANCH_INS 15 #define COP_REG_INS 16 -#define DCR_BRANCH_INS 17 -#define MMC_INS 18 -#define MMU_INS 19 +#define COPS_REG_INS 17 +#define DCR_BRANCH_INS 18 +#define MMC_INS 19 +#define MMU_INS 20 /* Maximum value supported for instruction types. */ #define CRX_INS_MAX (1 << 5) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 342c2f3..11b8a95 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +2004-10-07 Tomer Levi + + * crx-opc.c (crx_instruction): Support Co-processor insns. + * crx-dis.c (COP_ARG_TYPE): New enum for CO-Processor arguments. + (getregliststring): Change function to use the above enum. + (print_arg): Handle CO-Processor insns. + (crx_cinvs): Add 'b' option to invalidate the branch-target + cache. + 2004-10-06 Aldy Hernandez * ppc-opc.c (powerpc_opcodes): Add efscfd, efdabs, efdnabs, diff --git a/opcodes/crx-dis.c b/opcodes/crx-dis.c index 5796a2e..b2cf312 100644 --- a/opcodes/crx-dis.c +++ b/opcodes/crx-dis.c @@ -59,10 +59,25 @@ cinv_entry; /* CRX 'cinv' options. */ const cinv_entry crx_cinvs[] = { - {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, - {"[d,u]", 5}, {"[d,i]", 6}, {"[d,i,u]", 7} + {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, {"[d,u]", 5}, + {"[d,i]", 6}, {"[d,i,u]", 7}, {"[b]", 8}, + {"[b,i]", 10}, {"[b,i,u]", 11}, {"[b,d]", 12}, + {"[b,d,u]", 13}, {"[b,d,i]", 14}, {"[b,d,i,u]", 15} }; +/* Enum to distinguish CO-Processor [special] registers arguments + from general purpose regidters. */ +typedef enum COP_ARG_TYPE + { + /* Not a CO-Processor argument (probably a general purpose reg.). */ + NO_COP_ARG = 0, + /* A CO-Processor argument (c). */ + COP_ARG, + /* A CO-Processor special argument (cs). */ + COPS_ARG + } +COP_ARG_TYPE; + /* Number of valid 'cinv' instruction options. */ int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0])); /* Current opcode table entry we're disassembling. */ @@ -89,7 +104,7 @@ static char *getcopregname (copreg, reg_type); static char * getprocregname (int); static char *gettrapstring (unsigned); static char *getcinvstring (unsigned); -static void getregliststring (int, char *, int); +static void getregliststring (int, char *, enum COP_ARG_TYPE); static wordU get_word_at_PC (bfd_vma, struct disassemble_info *); static void get_words_at_PC (bfd_vma, struct disassemble_info *); static unsigned long build_mask (void); @@ -225,7 +240,7 @@ powerof2 (int x) /* Transform a register bit mask to a register list. */ void -getregliststring (int trap, char *string, int core_cop) +getregliststring (int trap, char *string, enum COP_ARG_TYPE core_cop) { char temp_string[5]; int i; @@ -236,11 +251,21 @@ getregliststring (int trap, char *string, int core_cop) for (i = 0; i < 16; i++) { if (trap & 0x1) - { - if (core_cop) - sprintf (temp_string, "r%d", i); - else - sprintf (temp_string, "c%d", i); + { + switch (core_cop) + { + case NO_COP_ARG: + sprintf (temp_string, "r%d", i); + break; + case COP_ARG: + sprintf (temp_string, "c%d", i); + break; + case COPS_ARG: + sprintf (temp_string, "cs%d", i); + break; + default: + break; + } strcat (string, temp_string); if (trap & 0xfffe) strcat (string, ","); @@ -490,22 +515,26 @@ print_arg (argument *a, struct disassemble_info *info) else if (INST_HAS_REG_LIST) { - if (!IS_INSN_TYPE (COP_REG_INS)) + COP_ARG_TYPE cop_ins = IS_INSN_TYPE (COP_REG_INS) ? + COP_ARG : IS_INSN_TYPE (COPS_REG_INS) ? + COPS_ARG : NO_COP_ARG; + + if (cop_ins != NO_COP_ARG) + { + /* Check for proper argument number. */ + if (processing_argument_number == 2) + { + getregliststring (a->constant, string, cop_ins); + func (stream, "%s", string); + } + else + func (stream, "$0x%x", a->constant); + } + else { - getregliststring (a->constant, string, 1); + getregliststring (a->constant, string, cop_ins); func (stream, "%s", string); } - else - { - /* Check for proper argument number. */ - if (processing_argument_number == 2) - { - getregliststring (a->constant, string, 0); - func (stream, "%s", string); - } - else - func (stream, "$0x%x", a->constant); - } } else func (stream, "$0x%x", a->constant); diff --git a/opcodes/crx-opc.c b/opcodes/crx-opc.c index b01addf..846b78c 100644 --- a/opcodes/crx-opc.c +++ b/opcodes/crx-opc.c @@ -488,39 +488,55 @@ const inst crx_instruction[] = BR_INST ("bal", 0x307, 0x317, 0), - /* Decrement and Branch instructions */ + /* Decrement and Branch instructions. */ BR_INST ("dbnzb", 0x304, 0x314, DCR_BRANCH_INS), BR_INST ("dbnzw", 0x305, 0x315, DCR_BRANCH_INS), BR_INST ("dbnzd", 0x306, 0x316, DCR_BRANCH_INS), - /* Jump and link instructions */ + /* Jump and link instructions. */ REG1_INST ("jal", 0xFF8), REG2_INST ("jal", 0x37), REG2_INST ("jalid", 0x33), - /* opc12 c4 opc12 r mask16 */ - {"loadmcr", 3, 0x3110300, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}}, - {"stormcr", 3, 0x3110301, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}}, - - /* esc16 r procreg */ - {"mtpr", 2, 0x3009, 16, 0, {{regr8,8}, {regr8,0}}}, - /* esc16 procreg r */ - {"mfpr", 2, 0x300A, 16, 0, {{regr8,8}, {regr8,0}}}, - /* opc12 c4 opc8 r copreg */ - {"mtcr", 2, 0x301030, 8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copregr,0}}}, - /* opc12 c4 opc8 copreg r */ - {"mfcr", 2, 0x301031, 8, COP_REG_INS | FMT_2, {{i4,16}, {copregr,4}, {regr,0}}}, - /* opc12 c4 opc8 r copsreg */ - {"mtcsr", 2, 0x301032, 8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copsregr,0}}}, - /* opc12 c4 opc8 copsreg r */ - {"mfcsr", 2, 0x301033, 8, COP_REG_INS | FMT_2, {{i4,16}, {copsregr,4}, {regr,0}}}, - - /* CO-processor extensions */ +/* Create a CO-processor instruction. */ +#define COP_INST(NAME, OPC, TYPE, REG1, REG2) \ + /* opc12 c4 opc8 REG1 REG2 */ \ + {NAME, 2, 0x301030+OPC, 8, TYPE | FMT_2, {{i4,16}, {REG1,4}, {REG2,0}}} + + COP_INST ("mtcr", 0, COP_REG_INS, regr, copregr), + COP_INST ("mfcr", 1, COP_REG_INS, copregr, regr), + COP_INST ("mtcsr", 2, COPS_REG_INS, regr, copsregr), + COP_INST ("mfcsr", 3, COPS_REG_INS, copsregr, regr), + COP_INST ("ldcr", 4, COP_REG_INS, regr, copregr), + COP_INST ("stcr", 5, COP_REG_INS, regr, copregr), + COP_INST ("ldcsr", 6, COPS_REG_INS, regr, copsregr), + COP_INST ("stcsr", 7, COPS_REG_INS, regr, copsregr), + +/* Create a memory-related CO-processor instruction. */ +#define COPMEM_INST(NAME, OPC, TYPE) \ + /* opc12 c4 opc12 r mask16 */ \ + {NAME, 3, 0x3110300+OPC, 4, TYPE | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}} + + COPMEM_INST("loadmcr", 0, COP_REG_INS), + COPMEM_INST("stormcr", 1, COP_REG_INS), + COPMEM_INST("loadmcsr", 2, COPS_REG_INS), + COPMEM_INST("stormcsr", 3, COPS_REG_INS), + + /* CO-processor extensions. */ /* opc12 c4 opc4 i4 disps9 */ {"bcop", 2, 0x30107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d9,0}}}, /* opc12 c4 opc4 i4 disps25 */ {"bcop", 3, 0x31107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d25,0}}}, + /* opc12 c4 opc4 cpdo r r */ + {"cpdop", 2, 0x3010B, 12, COP_REG_INS | FMT_4, {{i4,16}, {i4,8}, {regr,4}, {regr,0}}}, + /* opc12 c4 opc4 cpdo r r cpdo16 */ + {"cpdop", 3, 0x3110B, 12, COP_REG_INS | FMT_4, {{i4,16}, {i4,8}, {regr,4}, {regr,0}, {i16,0}}}, + /* esc16 r procreg */ + {"mtpr", 2, 0x3009, 16, 0, {{regr8,8}, {regr8,0}}}, + /* esc16 procreg r */ + {"mfpr", 2, 0x300A, 16, 0, {{regr8,8}, {regr8,0}}}, + /* Miscellaneous. */ /* opc12 i4 */ {"excp", 1, 0xFFF, 20, 0, {{i4,16}}}, /* opc28 i4 */ -- 2.7.4