Fix the mask for the sqrdml(a|s)h instructions.
[deliverable/binutils-gdb.git] / opcodes / riscv-opc.c
index 27b4b9fb513c8e642971fe6252bee9285a41d7d3..a285b147b47f0e3fc4c329aee63c0987872df1d5 100644 (file)
@@ -1,5 +1,5 @@
 /* RISC-V opcode list
-   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   Copyright (C) 2011-2018 Free Software Foundation, Inc.
 
    Contributed by Andrew Waterman (andrew@sifive.com).
    Based on MIPS target.
@@ -113,10 +113,53 @@ match_c_add (const struct riscv_opcode *op, insn_t insn)
   return match_rd_nonzero (op, insn) && ((insn & MASK_CRS2) != 0);
 }
 
+/* We don't allow mv zero,X to become a c.mv hint, so we need a separate
+   matching function for this.  */
+
+static int
+match_c_add_with_hint (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_opcode (op, insn) && ((insn & MASK_CRS2) != 0);
+}
+
+static int
+match_c_nop (const struct riscv_opcode *op, insn_t insn)
+{
+  return (match_opcode (op, insn)
+         && (((insn & MASK_RD) >> OP_SH_RD) == 0));
+}
+
+static int
+match_c_addi16sp (const struct riscv_opcode *op, insn_t insn)
+{
+  return (match_opcode (op, insn)
+         && (((insn & MASK_RD) >> OP_SH_RD) == 2)
+         && EXTRACT_RVC_ADDI16SP_IMM (insn) != 0);
+}
+
 static int
 match_c_lui (const struct riscv_opcode *op, insn_t insn)
 {
-  return match_rd_nonzero (op, insn) && (((insn & MASK_RD) >> OP_SH_RD) != 2);
+  return (match_rd_nonzero (op, insn)
+         && (((insn & MASK_RD) >> OP_SH_RD) != 2)
+         && EXTRACT_RVC_LUI_IMM (insn) != 0);
+}
+
+/* We don't allow lui zero,X to become a c.lui hint, so we need a separate
+   matching function for this.  */
+
+static int
+match_c_lui_with_hint (const struct riscv_opcode *op, insn_t insn)
+{
+  return (match_opcode (op, insn)
+         && (((insn & MASK_RD) >> OP_SH_RD) != 2)
+         && EXTRACT_RVC_LUI_IMM (insn) != 0);
+}
+
+static int
+match_c_addi4spn (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_opcode (op, insn) && EXTRACT_RVC_ADDI4SPN_IMM (insn) != 0;
 }
 
 const struct riscv_opcode riscv_opcodes[] =
@@ -155,19 +198,18 @@ const struct riscv_opcode riscv_opcodes[] =
 {"lui",       "C",   "d,Cu",  MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS },
 {"lui",       "I",   "d,u",  MATCH_LUI, MASK_LUI, match_opcode, 0 },
 {"li",        "C",   "d,Cv",  MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS },
-{"li",        "C",   "d,Cj",  MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS },
-{"li",        "C",   "d,0",  MATCH_C_LI, MASK_C_LI | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
+{"li",        "C",   "d,Co",  MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS },
 {"li",        "I",   "d,j",      MATCH_ADDI, MASK_ADDI | MASK_RS1, match_opcode, INSN_ALIAS }, /* addi */
 {"li",        "I",   "d,I",  0,    (int) M_LI,  match_never, INSN_MACRO },
 {"mv",        "C",   "d,CV",  MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
 {"mv",        "I",   "d,s",  MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
 {"move",      "C",   "d,CV",  MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
 {"move",      "I",   "d,s",  MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
-{"andi",      "C",   "Cs,Cw,Cj",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
+{"andi",      "C",   "Cs,Cw,Co",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
 {"andi",      "I",   "d,s,j",  MATCH_ANDI, MASK_ANDI, match_opcode, 0 },
 {"and",       "C",   "Cs,Cw,Ct",  MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
 {"and",       "C",   "Cs,Ct,Cw",  MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
-{"and",       "C",   "Cs,Cw,Cj",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
+{"and",       "C",   "Cs,Cw,Co",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
 {"and",       "I",   "d,s,t",  MATCH_AND, MASK_AND, match_opcode, 0 },
 {"and",       "I",   "d,s,j",  MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS },
 {"beqz",      "C",   "Cs,Cp",  MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS },
@@ -188,16 +230,19 @@ const struct riscv_opcode riscv_opcodes[] =
 {"bnez",      "C",   "Cs,Cp",  MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS },
 {"bnez",      "I",   "s,p",  MATCH_BNE, MASK_BNE | MASK_RS2, match_opcode, INSN_ALIAS },
 {"bne",       "I",   "s,t,p",  MATCH_BNE, MASK_BNE, match_opcode, 0 },
-{"addi",      "C",   "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, INSN_ALIAS },
+{"addi",      "C",   "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
 {"addi",      "C",   "d,CU,Cj",  MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
-{"addi",      "C",   "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, INSN_ALIAS },
+{"addi",      "C",   "d,CU,z",    MATCH_C_NOP, MASK_C_ADDI | MASK_RVC_IMM, match_c_nop, INSN_ALIAS },
+{"addi",      "C",   "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
 {"addi",      "I",   "d,s,j",  MATCH_ADDI, MASK_ADDI, match_opcode, 0 },
 {"add",       "C",   "d,CU,CV",  MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
 {"add",       "C",   "d,CV,CU",  MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
-{"add",       "C",   "d,CU,Cj",  MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
-{"add",       "C",   "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, INSN_ALIAS },
-{"add",       "C",   "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, INSN_ALIAS },
+{"add",       "C",   "d,CU,Co",  MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
+{"add",       "C",   "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
+{"add",       "C",   "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
 {"add",       "I",   "d,s,t",  MATCH_ADD, MASK_ADD, match_opcode, 0 },
+/* This is used for TLS, where the fourth arg is %tprel_add, to get a reloc
+   applied to an add instruction, for relaxation to use.  */
 {"add",       "I",   "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, 0 },
 {"add",       "I",   "d,s,j",  MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS },
 {"la",        "I",   "d,A",  0,    (int) M_LA,  match_never, INSN_MACRO },
@@ -289,11 +334,11 @@ const struct riscv_opcode riscv_opcodes[] =
 {"sd",        "64I", "t,A,s",  0, (int) M_SD, match_never, INSN_MACRO },
 {"sext.w",    "64C", "d,CU",  MATCH_C_ADDIW, MASK_C_ADDIW | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
 {"sext.w",    "64I", "d,s",  MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS },
-{"addiw",     "64C", "d,CU,Cj",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
+{"addiw",     "64C", "d,CU,Co",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
 {"addiw",     "64I", "d,s,j",  MATCH_ADDIW, MASK_ADDIW, match_opcode, 0 },
 {"addw",      "64C", "Cs,Cw,Ct",  MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS },
 {"addw",      "64C", "Cs,Ct,Cw",  MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS },
-{"addw",      "64C", "d,CU,Cj",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
+{"addw",      "64C", "d,CU,Co",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
 {"addw",      "64I", "d,s,t",  MATCH_ADDW, MASK_ADDW, match_opcode, 0 },
 {"addw",      "64I", "d,s,j",  MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS },
 {"negw",      "64I", "d,t",  MATCH_SUBW, MASK_SUBW | MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */
@@ -424,9 +469,13 @@ const struct riscv_opcode riscv_opcodes[] =
 {"frrm",      "F",   "d",  MATCH_FRRM, MASK_FRRM, match_opcode, 0 },
 {"fsrm",      "F",   "s",  MATCH_FSRM, MASK_FSRM | MASK_RD, match_opcode, 0 },
 {"fsrm",      "F",   "d,s",  MATCH_FSRM, MASK_FSRM, match_opcode, 0 },
+{"fsrmi",     "F",   "d,Z",  MATCH_FSRMI, MASK_FSRMI, match_opcode, 0 },
+{"fsrmi",     "F",   "Z",  MATCH_FSRMI, MASK_FSRMI | MASK_RD, match_opcode, 0 },
 {"frflags",   "F",   "d",  MATCH_FRFLAGS, MASK_FRFLAGS, match_opcode, 0 },
 {"fsflags",   "F",   "s",  MATCH_FSFLAGS, MASK_FSFLAGS | MASK_RD, match_opcode, 0 },
 {"fsflags",   "F",   "d,s",  MATCH_FSFLAGS, MASK_FSFLAGS, match_opcode, 0 },
+{"fsflagsi",  "F",   "d,Z",  MATCH_FSFLAGSI, MASK_FSFLAGSI, match_opcode, 0 },
+{"fsflagsi",  "F",   "Z",  MATCH_FSFLAGSI, MASK_FSFLAGSI | MASK_RD, match_opcode, 0 },
 {"flw",       "32C", "D,Cm(Cc)",  MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, INSN_ALIAS },
 {"flw",       "32C", "CD,Ck(Cs)",  MATCH_C_FLW, MASK_C_FLW, match_opcode, INSN_ALIAS },
 {"flw",       "F",   "D,o(s)",  MATCH_FLW, MASK_FLW, match_opcode, 0 },
@@ -625,18 +674,19 @@ const struct riscv_opcode riscv_opcodes[] =
 {"c.swsp",    "C",   "CV,CM(Cc)",  MATCH_C_SWSP, MASK_C_SWSP, match_opcode, 0 },
 {"c.sw",      "C",   "Ct,Ck(Cs)",  MATCH_C_SW, MASK_C_SW, match_opcode, 0 },
 {"c.nop",     "C",   "",  MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS },
-{"c.mv",      "C",   "d,CV",  MATCH_C_MV, MASK_C_MV, match_c_add, 0 },
-{"c.lui",     "C",   "d,Cu",  MATCH_C_LUI, MASK_C_LUI, match_c_lui, 0 },
-{"c.li",      "C",   "d,Co",  MATCH_C_LI, MASK_C_LI, match_rd_nonzero, 0 },
-{"c.addi4spn","C",   "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, 0 },
-{"c.addi16sp","C",   "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, 0 },
-{"c.addi",    "C",   "d,Cj",  MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 },
-{"c.add",     "C",   "d,CV",  MATCH_C_ADD, MASK_C_ADD, match_c_add, 0 },
+{"c.nop",     "C",   "Cj",  MATCH_C_ADDI, MASK_C_ADDI | MASK_RD, match_opcode, INSN_ALIAS },
+{"c.mv",      "C",   "d,CV",  MATCH_C_MV, MASK_C_MV, match_c_add_with_hint, 0 },
+{"c.lui",     "C",   "d,Cu",  MATCH_C_LUI, MASK_C_LUI, match_c_lui_with_hint, 0 },
+{"c.li",      "C",   "d,Co",  MATCH_C_LI, MASK_C_LI, match_opcode, 0 },
+{"c.addi4spn","C",   "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, 0 },
+{"c.addi16sp","C",   "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, 0 },
+{"c.addi",    "C",   "d,Co",  MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 },
+{"c.add",     "C",   "d,CV",  MATCH_C_ADD, MASK_C_ADD, match_c_add_with_hint, 0 },
 {"c.sub",     "C",   "Cs,Ct",  MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 },
 {"c.and",     "C",   "Cs,Ct",  MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
 {"c.or",      "C",   "Cs,Ct",  MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
 {"c.xor",     "C",   "Cs,Ct",  MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
-{"c.slli",    "C",   "d,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, 0 },
+{"c.slli",    "C",   "d,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_opcode, 0 },
 {"c.srli",    "C",   "Cs,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 },
 {"c.srai",    "C",   "Cs,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 },
 {"c.andi",    "C",   "Cs,Co",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
@@ -691,3 +741,77 @@ const struct riscv_opcode riscv_opcodes[] =
 /* Terminate the list.  */
 {0, 0, 0, 0, 0, 0, 0}
 };
+
+/* Instruction format for .insn directive.  */
+const struct riscv_opcode riscv_insn_types[] =
+{
+/* name,  isa,          operands, match, mask,    match_func, pinfo.  */
+{"r",     "I",  "O4,F3,F7,d,s,t",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,D,s,t",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,d,S,t",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,D,S,t",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,d,s,T",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,D,s,T",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,d,S,T",     0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F7,D,S,T",     0,    0,  match_opcode, 0 },
+
+{"r",     "I",  "O4,F3,F2,d,s,t,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,s,t,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,S,t,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,S,t,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,s,T,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,s,T,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,S,T,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,S,T,r",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,s,t,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,s,t,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,S,t,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,S,t,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,s,T,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,s,T,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,d,S,T,R",   0,    0,  match_opcode, 0 },
+{"r",     "I",  "O4,F3,F2,D,S,T,R",   0,    0,  match_opcode, 0 },
+
+{"i",     "I",  "O4,F3,d,s,j",        0,    0,  match_opcode, 0 },
+{"i",     "I",  "O4,F3,D,s,j",        0,    0,  match_opcode, 0 },
+{"i",     "I",  "O4,F3,d,S,j",        0,    0,  match_opcode, 0 },
+{"i",     "I",  "O4,F3,D,S,j",        0,    0,  match_opcode, 0 },
+
+{"i",     "I",  "O4,F3,d,o(s)",       0,    0,  match_opcode, 0 },
+{"i",     "I",  "O4,F3,D,o(s)",       0,    0,  match_opcode, 0 },
+
+{"s",     "I",  "O4,F3,d,o(s)",       0,    0,  match_opcode, 0 },
+{"s",     "I",  "O4,F3,D,o(s)",       0,    0,  match_opcode, 0 },
+
+{"sb",    "I",  "O4,F3,s,t,p",        0,    0,  match_opcode, 0 },
+{"sb",    "I",  "O4,F3,S,t,p",        0,    0,  match_opcode, 0 },
+{"sb",    "I",  "O4,F3,s,T,p",        0,    0,  match_opcode, 0 },
+{"sb",    "I",  "O4,F3,S,T,p",        0,    0,  match_opcode, 0 },
+
+{"sb",    "I",  "O4,F3,t,q(s)",       0,    0,  match_opcode, 0 },
+{"sb",    "I",  "O4,F3,T,q(s)",       0,    0,  match_opcode, 0 },
+
+{"u",     "I",  "O4,d,u",             0,    0,  match_opcode, 0 },
+{"u",     "I",  "O4,D,u",             0,    0,  match_opcode, 0 },
+
+{"uj",    "I",  "O4,d,a",             0,    0,  match_opcode, 0 },
+{"uj",    "I",  "O4,D,a",             0,    0,  match_opcode, 0 },
+
+{"cr",    "C",  "O2,CF4,d,CV",        0,    0,  match_opcode, 0 },
+{"cr",    "C",  "O2,CF4,D,CV",        0,    0,  match_opcode, 0 },
+{"cr",    "C",  "O2,CF4,d,CT",        0,    0,  match_opcode, 0 },
+{"cr",    "C",  "O2,CF4,D,CT",        0,    0,  match_opcode, 0 },
+
+{"ci",    "C",  "O2,CF3,d,Co",        0,    0,  match_opcode, 0 },
+{"ci",    "C",  "O2,CF3,D,Co",        0,    0,  match_opcode, 0 },
+
+{"ciw",   "C",  "O2,CF3,Ct,C8",        0,    0,  match_opcode, 0 },
+{"ciw",   "C",  "O2,CF3,CD,C8",        0,    0,  match_opcode, 0 },
+
+{"cb",    "C",  "O2,CF3,Cs,Cp",       0,    0,  match_opcode, 0 },
+{"cb",    "C",  "O2,CF3,CS,Cp",       0,    0,  match_opcode, 0 },
+
+{"cj",    "C",  "O2,CF3,Ca",          0,    0,  match_opcode, 0 },
+/* Terminate the list.  */
+{0, 0, 0, 0, 0, 0, 0}
+};
This page took 0.038715 seconds and 4 git commands to generate.