summaryrefslogtreecommitdiff
path: root/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-xilinx/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch')
-rw-r--r--meta-xilinx/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch359
1 files changed, 359 insertions, 0 deletions
diff --git a/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch b/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch
new file mode 100644
index 000000000..8141095a2
--- /dev/null
+++ b/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch
@@ -0,0 +1,359 @@
+From 7b332d61cb3dbcae69021ce706f2c408c85af193 Mon Sep 17 00:00:00 2001
+From: Nagaraju <nmekala@xilinx.com>
+Date: Fri, 23 Aug 2019 16:18:43 +0530
+Subject: [PATCH 30/43] Added support to new arithmetic single register
+ instructions
+
+---
+ gas/config/tc-microblaze.c | 147 ++++++++++++++++++++++++++++++++++++-
+ opcodes/microblaze-dis.c | 12 +++
+ opcodes/microblaze-opc.h | 43 ++++++++++-
+ opcodes/microblaze-opcm.h | 5 +-
+ 4 files changed, 201 insertions(+), 6 deletions(-)
+
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 5b506d3348..12eef24a29 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -423,12 +423,33 @@ void
+ md_begin (void)
+ {
+ struct op_code_struct * opcode;
++ const char *prev_name = "";
+
+ opcode_hash_control = hash_new ();
+
+ /* Insert unique names into hash table. */
+- for (opcode = opcodes; opcode->name; opcode ++)
+- hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
++ for (opcode = (struct opcodes *)opcodes; opcode->name; opcode ++)
++ {
++ if (strcmp (prev_name, opcode->name))
++ {
++ prev_name = (char *) opcode->name;
++ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
++ }
++ }
++}
++
++static int
++is_reg (char * s)
++{
++ int is_reg = 0;
++ /* Strip leading whitespace. */
++ while (ISSPACE (* s))
++ ++ s;
++ if (TOLOWER (s[0]) == 'r')
++ {
++ is_reg =1;
++ }
++ return is_reg;
+ }
+
+ /* Try to parse a reg name. */
+@@ -986,6 +1007,7 @@ md_assemble (char * str)
+ {
+ char * op_start;
+ char * op_end;
++ char * temp_op_end;
+ struct op_code_struct * opcode, *opcode1;
+ char * output = NULL;
+ int nlen = 0;
+@@ -996,9 +1018,10 @@ md_assemble (char * str)
+ unsigned reg3;
+ unsigned isize;
+ unsigned long immed, immed2, temp;
+- expressionS exp;
++ expressionS exp,exp1;
+ char name[20];
+ long immedl;
++ int reg=0;
+
+ /* Drop leading whitespace. */
+ while (ISSPACE (* str))
+@@ -1029,7 +1052,78 @@ md_assemble (char * str)
+ as_bad (_("unknown opcode \"%s\""), name);
+ return;
+ }
+-
++
++ if ((microblaze_arch_size == 64) && (streq (name, "addli") || streq (name, "addlic") ||
++ streq (name, "addlik") || streq (name, "addlikc") || streq (name, "rsubli")
++ || streq (name, "rsublic") || streq (name, "rsublik") || streq (name, "rsublikc")
++ || streq (name, "andli") || streq (name, "andnli") || streq (name, "orli")
++ || streq (name, "xorli")))
++ {
++ temp_op_end = op_end;
++ if (strcmp (temp_op_end, ""))
++ temp_op_end = parse_reg (temp_op_end + 1, &reg1); /* Get rd. */
++ if (strcmp (temp_op_end, ""))
++ reg = is_reg (temp_op_end + 1);
++ if (reg)
++ {
++
++ opcode->inst_type=INST_TYPE_RD_R1_IMML;
++ opcode->inst_offset_type = OPCODE_MASK_H;
++ if (streq (name, "addli"))
++ opcode->bit_sequence = ADDLI_MASK;
++ else if (streq (name, "addlic"))
++ opcode->bit_sequence = ADDLIC_MASK;
++ else if (streq (name, "addlik"))
++ opcode->bit_sequence = ADDLIK_MASK;
++ else if (streq (name, "addlikc"))
++ opcode->bit_sequence = ADDLIKC_MASK;
++ else if (streq (name, "rsubli"))
++ opcode->bit_sequence = RSUBLI_MASK;
++ else if (streq (name, "rsublic"))
++ opcode->bit_sequence = RSUBLIC_MASK;
++ else if (streq (name, "rsublik"))
++ opcode->bit_sequence = RSUBLIK_MASK;
++ else if (streq (name, "rsublikc"))
++ opcode->bit_sequence = RSUBLIKC_MASK;
++ else if (streq (name, "andli"))
++ opcode->bit_sequence = ANDLI_MASK;
++ else if (streq (name, "andnli"))
++ opcode->bit_sequence = ANDLNI_MASK;
++ else if (streq (name, "orli"))
++ opcode->bit_sequence = ORLI_MASK;
++ else if (streq (name, "xorli"))
++ opcode->bit_sequence = XORLI_MASK;
++ }
++ else
++ {
++ opcode->inst_type=INST_TYPE_RD_IMML;
++ opcode->inst_offset_type = OPCODE_MASK_LIMM;
++ if (streq (name, "addli"))
++ opcode->bit_sequence = ADDLI_ONE_REG_MASK;
++ else if (streq (name, "addlic"))
++ opcode->bit_sequence = ADDLIC_ONE_REG_MASK;
++ else if (streq (name, "addlik"))
++ opcode->bit_sequence = ADDLIK_ONE_REG_MASK;
++ else if (streq (name, "addlikc"))
++ opcode->bit_sequence = ADDLIKC_ONE_REG_MASK;
++ else if (streq (name, "rsubli"))
++ opcode->bit_sequence = RSUBLI_ONE_REG_MASK;
++ else if (streq (name, "rsublic"))
++ opcode->bit_sequence = RSUBLIC_ONE_REG_MASK;
++ else if (streq (name, "rsublik"))
++ opcode->bit_sequence = RSUBLIK_ONE_REG_MASK;
++ else if (streq (name, "rsublikc"))
++ opcode->bit_sequence = RSUBLIKC_ONE_REG_MASK;
++ else if (streq (name, "andli"))
++ opcode->bit_sequence = ANDLI_ONE_REG_MASK;
++ else if (streq (name, "andnli"))
++ opcode->bit_sequence = ANDLNI_ONE_REG_MASK;
++ else if (streq (name, "orli"))
++ opcode->bit_sequence = ORLI_ONE_REG_MASK;
++ else if (streq (name, "xorli"))
++ opcode->bit_sequence = XORLI_ONE_REG_MASK;
++ }
++ }
+ inst = opcode->bit_sequence;
+ isize = 4;
+
+@@ -1480,6 +1574,51 @@ md_assemble (char * str)
+ inst |= (immed << IMM_LOW) & IMM15_MASK;
+ break;
+
++ case INST_TYPE_RD_IMML:
++ if (strcmp (op_end, ""))
++ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
++ else
++ {
++ as_fatal (_("Error in statement syntax"));
++ reg1 = 0;
++ }
++
++ if (strcmp (op_end, ""))
++ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
++ else
++ as_fatal (_("Error in statement syntax"));
++
++ /* Check for spl registers. */
++ if (check_spl_reg (&reg1))
++ as_fatal (_("Cannot use special register with this instruction"));
++ if (exp.X_op != O_constant)
++ {
++ char *opc = NULL;
++ relax_substateT subtype;
++
++ if (exp.X_md != 0)
++ subtype = get_imm_otype(exp.X_md);
++ else
++ subtype = opcode->inst_offset_type;
++
++ output = frag_var (rs_machine_dependent,
++ isize * 2,
++ isize * 2,
++ subtype,
++ exp.X_add_symbol,
++ exp.X_add_number,
++ (char *) opc);
++ immedl = 0L;
++ }
++ else
++ {
++ output = frag_more (isize);
++ immed = exp.X_add_number;
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (immed << IMM_LOW) & IMM16_MASK;
++ break;
++
+ case INST_TYPE_R1_RFSL:
+ if (strcmp (op_end, ""))
+ op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
+diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
+index f679a43606..e5e880cb1c 100644
+--- a/opcodes/microblaze-dis.c
++++ b/opcodes/microblaze-dis.c
+@@ -114,6 +114,15 @@ get_field_imm15 (long instr)
+ return (strdup (tmpstr));
+ }
+
++static char *
++get_field_imm16 (long instr)
++{
++ char tmpstr[25];
++
++ sprintf (tmpstr, "%d", (short)((instr & IMM16_MASK) >> IMM_LOW));
++ return (strdup (tmpstr));
++}
++
+ static char *
+ get_field_special (long instr, struct op_code_struct * op)
+ {
+@@ -419,6 +428,9 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
+ case INST_TYPE_RD_IMM15:
+ print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm15 (inst));
+ break;
++ case INST_TYPE_RD_IMML:
++ print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm16 (inst));
++ break;
+ /* For mbar insn. */
+ case INST_TYPE_IMM5:
+ print_func (stream, "\t%s", get_field_imm5_mbar (inst));
+diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
+index d59ee0a95f..0774f70e08 100644
+--- a/opcodes/microblaze-opc.h
++++ b/opcodes/microblaze-opc.h
+@@ -69,6 +69,7 @@
+ #define INST_TYPE_RD_R1_IMMW_IMMS 21
+
+ #define INST_TYPE_NONE 25
++#define INST_TYPE_RD_IMML 26
+
+
+
+@@ -84,6 +85,7 @@
+ #define IMMVAL_MASK_MFS 0x0000
+
+ #define OPCODE_MASK_H 0xFC000000 /* High 6 bits only. */
++#define OPCODE_MASK_LIMM 0xFC1F0000 /* High 6 bits and 12-16 bits */
+ #define OPCODE_MASK_H1 0xFFE00000 /* High 11 bits. */
+ #define OPCODE_MASK_H2 0xFC1F0000 /* High 6 and bits 20-16. */
+ #define OPCODE_MASK_H12 0xFFFF0000 /* High 16. */
+@@ -106,6 +108,33 @@
+ #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
+ #define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */
+
++/*Defines to identify 64-bit single reg instructions */
++#define ADDLI_ONE_REG_MASK 0x68000000
++#define ADDLIC_ONE_REG_MASK 0x68020000
++#define ADDLIK_ONE_REG_MASK 0x68040000
++#define ADDLIKC_ONE_REG_MASK 0x68060000
++#define RSUBLI_ONE_REG_MASK 0x68010000
++#define RSUBLIC_ONE_REG_MASK 0x68030000
++#define RSUBLIK_ONE_REG_MASK 0x68050000
++#define RSUBLIKC_ONE_REG_MASK 0x68070000
++#define ORLI_ONE_REG_MASK 0x68100000
++#define ANDLI_ONE_REG_MASK 0x68110000
++#define XORLI_ONE_REG_MASK 0x68120000
++#define ANDLNI_ONE_REG_MASK 0x68130000
++#define ADDLI_MASK 0x20000000
++#define ADDLIC_MASK 0x28000000
++#define ADDLIK_MASK 0x30000000
++#define ADDLIKC_MASK 0x38000000
++#define RSUBLI_MASK 0x24000000
++#define RSUBLIC_MASK 0x2C000000
++#define RSUBLIK_MASK 0x34000000
++#define RSUBLIKC_MASK 0x3C000000
++#define ANDLI_MASK 0xA4000000
++#define ANDLNI_MASK 0xAC000000
++#define ORLI_MASK 0xA0000000
++#define XORLI_MASK 0xA8000000
++
++
+ /* New Mask for msrset, msrclr insns. */
+ #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
+ /* Mask for mbar insn. */
+@@ -114,7 +143,7 @@
+ #define DELAY_SLOT 1
+ #define NO_DELAY_SLOT 0
+
+-#define MAX_OPCODES 412
++#define MAX_OPCODES 424
+
+ struct op_code_struct
+ {
+@@ -444,13 +473,21 @@ struct op_code_struct
+ {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst },
+ {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst },
+ {"addli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68000000, OPCODE_MASK_LIMM, addli, arithmetic_inst },
+ {"rsubli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsubli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68010000, OPCODE_MASK_LIMM, rsubli, arithmetic_inst },
+ {"addlic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addlic", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68020000, OPCODE_MASK_LIMM, addlic, arithmetic_inst },
+ {"rsublic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsublic", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68030000, OPCODE_MASK_LIMM, rsublic, arithmetic_inst },
+ {"addlik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addlik", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68040000, OPCODE_MASK_LIMM, addlik, arithmetic_inst },
+ {"rsublik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsublik", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68050000, OPCODE_MASK_LIMM, rsublik, arithmetic_inst },
+ {"addlikc", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addlikc", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68060000, OPCODE_MASK_LIMM, addlikc, arithmetic_inst },
+ {"rsublikc",INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsublikc", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68070000, OPCODE_MASK_LIMM, rsublikc, arithmetic_inst },
+ {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst },
+ {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst },
+ {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst },
+@@ -501,9 +538,13 @@ struct op_code_struct
+ {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst },
+ {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst },
+ {"orli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"orli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68100000, OPCODE_MASK_LIMM, orli, arithmetic_inst },
+ {"andli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"andli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68110000, OPCODE_MASK_LIMM, andli, arithmetic_inst },
+ {"xorli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"xorli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68120000, OPCODE_MASK_LIMM, xorli, arithmetic_inst },
+ {"andnli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"andnli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68130000, OPCODE_MASK_LIMM, andnli, arithmetic_inst },
+ {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst },
+ {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst },
+ {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst },
+diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
+index 5f2e190d23..4d2ee2dd0d 100644
+--- a/opcodes/microblaze-opcm.h
++++ b/opcodes/microblaze-opcm.h
+@@ -61,7 +61,9 @@ enum microblaze_instr
+ eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd,
+
+ /* 64-bit instructions */
+- addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
++ addl, addli, addlic, addlik, addlikc, rsubl, rsubli, rsublic, rsublik, rsublikc,
++ addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
++ andli, andnli, orli, xorli,
+ bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl,
+ andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32,
+ brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned,
+@@ -166,5 +168,6 @@ enum microblaze_instr_type
+
+ /* Imm mask for msrset, msrclr instructions. */
+ #define IMM15_MASK 0x00007FFF
++#define IMM16_MASK 0x0000FFFF
+
+ #endif /* MICROBLAZE-OPCM */
+--
+2.17.1
+