{ "instructions": [ { "mnemonic": "add", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "add.uw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "bropw_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_ADDUW => 0b00,\n RISCV_SH1ADDUW => 0b01,\n RISCV_SH2ADDUW => 0b10,\n RISCV_SH3ADDUW => 0b11\n };\n let result : xlenbits = (zero_extend(rs1_val[31..0]) << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "addi", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "iop" } ], "syntax": "rd,rs1,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "encdec_iop(op)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let immext : xlenbits = sign_extend(imm);\n let result : xlenbits = match op {\n RISCV_ADDI => rs1_val + immext,\n RISCV_SLTI => zero_extend(bool_to_bits(rs1_val <_s immext)),\n RISCV_SLTIU => zero_extend(bool_to_bits(rs1_val <_u immext)),\n RISCV_ANDI => rs1_val & immext,\n RISCV_ORI => rs1_val | immext,\n RISCV_XORI => rs1_val ^ immext\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe ITYPE instruction operates on an immediate value, adding, comparing, or\nperforming bitwise operations with the contents of register rs1.\nThe immediate value, rs1, and the operation code (iop) determine the operation.\nThe result is stored in register rd.\nThe supported immediate operations (iop) include:\n - \"addi\" : Add immediate\n - \"slti\" : Set less than immediate (signed)\n - \"sltiu\" : Set less than immediate (unsigned)\n - \"andi\" : AND immediate\n - \"ori\" : OR immediate\n - \"xori\" : XOR immediate\n *\nNote: The immediate value is sign-extended before performing the operation.\n " }, { "mnemonic": "addiw", "name": "Add Immediate Word", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,imm", "format": "I", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [], "function": "{\n let result : xlenbits = sign_extend(imm) + X(rs1);\n X(rd) = sign_extend(result[31..0]);\n RETIRE_SUCCESS\n}", "description": "\nThe ADDIW instruction involves adding a sign-extended\n12-bit immediate value to the content of register rs1. The result is a 32-bit\nvalue, and overflow is disregarded. The final outcome is the lower 32 bits of\nthe result, sign-extended to 64 bits. If the immediate value is set to zero\nin the ADDIW rd, rs1, 0 operation, the sign-extension of the lower 32 bits\nof register rs1 is written to register rd.\n " }, { "mnemonic": "addw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "ropw" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let rs2_val = (X(rs2))[31..0];\n let result : bits(32) = match op {\n RISCV_ADDW => rs1_val + rs2_val,\n RISCV_SUBW => rs1_val - rs2_val,\n RISCV_SLLW => rs1_val << (rs2_val[4..0]),\n RISCV_SRLW => rs1_val >> (rs2_val[4..0]),\n RISCV_SRAW => shift_right_arith32(rs1_val, rs2_val[4..0])\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe RTYPEW instruction set operates on 32-bit values,\nand the result is sign-extended to 64 bits. The available operations are\nADDW (addition), SUBW (subtraction), SLLW (logical left shift),\nSRLW (logical right shift), and SRAW (arithmetic right shift).\nThese operations are only applicable when the width of the target\narchitecture is 64 bits.\n " }, { "mnemonic": "aes32dsi", "name": "TBD", "operands": [ { "name": "bs", "type": "bits(2)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2,bs", "format": "TBD", "fields": [ { "field": "bs", "size": 2 }, { "field": "0b10101", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknd" ], "function": "{\n let shamt : bits( 5) = bs @ 0b000; /* shamt = bs*8 */\n let si : bits( 8) = (X(rs2) >> shamt)[7..0]; /* SBox Input */\n let so : bits(32) = 0x000000 @ aes_sbox_inv(si);\n let result : bits(32) = X(rs1)[31..0] ^ (so <<< shamt);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes32dsmi", "name": "TBD", "operands": [ { "name": "bs", "type": "bits(2)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2,bs", "format": "TBD", "fields": [ { "field": "bs", "size": 2 }, { "field": "0b10111", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknd" ], "function": "{\n let shamt : bits( 5) = bs @ 0b000; /* shamt = bs*8 */\n let si : bits( 8) = (X(rs2) >> shamt)[7..0]; /* SBox Input */\n let so : bits( 8) = aes_sbox_inv(si);\n let mixed : bits(32) = aes_mixcolumn_byte_inv(so);\n let result : bits(32) = X(rs1)[31..0] ^ (mixed <<< shamt);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes32esi", "name": "TBD", "operands": [ { "name": "bs", "type": "bits(2)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2,bs", "format": "TBD", "fields": [ { "field": "bs", "size": 2 }, { "field": "0b10001", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zkne" ], "function": "{\n let shamt : bits( 5) = bs @ 0b000; /* shamt = bs*8 */\n let si : bits( 8) = (X(rs2) >> shamt)[7..0]; /* SBox Input */\n let so : bits(32) = 0x000000 @ aes_sbox_fwd(si);\n let result : bits(32) = X(rs1)[31..0] ^ (so <<< shamt);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes32esmi", "name": "TBD", "operands": [ { "name": "bs", "type": "bits(2)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2,bs", "format": "TBD", "fields": [ { "field": "bs", "size": 2 }, { "field": "0b10011", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zkne" ], "function": "{\n let shamt : bits( 5) = bs @ 0b000; /* shamt = bs*8 */\n let si : bits( 8) = (X(rs2) >> shamt)[7..0]; /* SBox Input */\n let so : bits( 8) = aes_sbox_fwd(si);\n let mixed : bits(32) = aes_mixcolumn_byte_fwd(so);\n let result : bits(32) = X(rs1)[31..0] ^ (mixed <<< shamt);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64ds", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b11101", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknd" ], "function": "{\n assert(sizeof(xlen) == 64);\n let sr : bits(64) = aes_rv64_shiftrows_inv(X(rs2), X(rs1));\n let wd : bits(64) = sr[63..0];\n X(rd) = aes_apply_inv_sbox_to_each_byte(wd);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64dsm", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b11111", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknd" ], "function": "{\n assert(sizeof(xlen) == 64);\n let sr : bits(64) = aes_rv64_shiftrows_inv(X(rs2), X(rs1));\n let wd : bits(64) = sr[63..0];\n let sb : bits(64) = aes_apply_inv_sbox_to_each_byte(wd);\n X(rd) = aes_mixcolumn_inv(sb[63..32]) @ aes_mixcolumn_inv(sb[31..0]);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64es", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b11001", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zkne" ], "function": "{\n assert(sizeof(xlen) == 64);\n let sr : bits(64) = aes_rv64_shiftrows_fwd(X(rs2), X(rs1));\n let wd : bits(64) = sr[63..0];\n X(rd) = aes_apply_fwd_sbox_to_each_byte(wd);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64esm", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b11011", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zkne" ], "function": "{\n assert(sizeof(xlen) == 64);\n let sr : bits(64) = aes_rv64_shiftrows_fwd(X(rs2), X(rs1));\n let wd : bits(64) = sr[63..0];\n let sb : bits(64) = aes_apply_fwd_sbox_to_each_byte(wd);\n X(rd) = aes_mixcolumn_fwd(sb[63..32]) @ aes_mixcolumn_fwd(sb[31..0]);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64im", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b11000", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknd" ], "function": "{\n assert(sizeof(xlen) == 64);\n let w0 : bits(32) = aes_mixcolumn_inv(X(rs1)[31.. 0]);\n let w1 : bits(32) = aes_mixcolumn_inv(X(rs1)[63..32]);\n X(rd) = w1 @ w0;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64ks1i", "name": "TBD", "operands": [ { "name": "rnum", "type": "bits(4)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rnum", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b11000", "size": 5 }, { "field": "0b1", "size": 1 }, { "field": "rnum", "size": 4 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zkne", "Zknd" ], "function": "{\n assert(sizeof(xlen) == 64);\n let prev : bits(32) = X(rs1)[63..32];\n let subwords : bits(32) = aes_subword_fwd(prev);\n let result : bits(32) = if (rnum == 0xA) then subwords\n else (subwords >>> 8) ^ aes_decode_rcon(rnum);\n X(rd) = result @ result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "aes64ks2", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b11111", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zkne", "Zknd" ], "function": "{\n assert(sizeof(xlen) == 64);\n let w0 : bits(32) = X(rs1)[63..32] ^ X(rs2)[31..0];\n let w1 : bits(32) = X(rs1)[63..32] ^ X(rs2)[31..0] ^ X(rs2)[63..32];\n X(rd) = w1 @ w0;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "amoadd.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoadd.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoand.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomax.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomaxu.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amomin.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amominu.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoor.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoswap.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.b", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.b.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.b.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.b.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.d", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.d.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.d.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.d.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.h", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.h.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.h.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.h.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.w", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.w.aq", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.w.aq.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "amoxor.w.rl", "name": "TBD", "operands": [ { "name": "op", "type": "amoop" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs2,(rs1)", "format": "TBD", "fields": [ { "field": "encdec_amoop(op)", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Some extensions perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n match translateAddr(vaddr, ReadWrite(Data, Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n let is_unsigned : bool = match op {\n AMOMINU => true,\n AMOMAXU => true,\n _ => false\n };\n let rs2_val : xlenbits = match width {\n BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),\n HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),\n WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),\n DOUBLE => X(rs2)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {\n (BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),\n (HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),\n (WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),\n (DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (mval) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(loaded) => {\n let result : xlenbits =\n match op {\n AMOSWAP => rs2_val,\n AMOADD => rs2_val + loaded,\n AMOXOR => rs2_val ^ loaded,\n AMOAND => rs2_val & loaded,\n AMOOR => rs2_val | loaded,\n\n /* These operations convert bitvectors to integer values using [un]signed,\n * and back using to_bits().\n */\n AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),\n AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),\n AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),\n AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))\n };\n let rval : xlenbits = match width {\n BYTE => sign_extend(loaded[7..0]),\n HALF => sign_extend(loaded[15..0]),\n WORD => sign_extend(loaded[31..0]),\n DOUBLE => loaded\n };\n let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n };\n match (wval) {\n MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },\n MemValue(false) => { internal_error(__FILE__, __LINE__, \"AMO got false from mem_write_value\") },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "and", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "andi", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "iop" } ], "syntax": "rd,rs1,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "encdec_iop(op)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let immext : xlenbits = sign_extend(imm);\n let result : xlenbits = match op {\n RISCV_ADDI => rs1_val + immext,\n RISCV_SLTI => zero_extend(bool_to_bits(rs1_val <_s immext)),\n RISCV_SLTIU => zero_extend(bool_to_bits(rs1_val <_u immext)),\n RISCV_ANDI => rs1_val & immext,\n RISCV_ORI => rs1_val | immext,\n RISCV_XORI => rs1_val ^ immext\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe ITYPE instruction operates on an immediate value, adding, comparing, or\nperforming bitwise operations with the contents of register rs1.\nThe immediate value, rs1, and the operation code (iop) determine the operation.\nThe result is stored in register rd.\nThe supported immediate operations (iop) include:\n - \"addi\" : Add immediate\n - \"slti\" : Set less than immediate (signed)\n - \"sltiu\" : Set less than immediate (unsigned)\n - \"andi\" : AND immediate\n - \"ori\" : OR immediate\n - \"xori\" : XOR immediate\n *\nNote: The immediate value is sign-extended before performing the operation.\n " }, { "mnemonic": "andn", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "auipc", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(20)" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "uop" } ], "syntax": "rd,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 20 }, { "field": "rd", "size": 5 }, { "field": "encdec_uop(op)", "size": 7 } ], "extensions": [], "function": "{\n let off : xlenbits = sign_extend(imm @ 0x000);\n let ret : xlenbits = match op {\n RISCV_LUI => off,\n RISCV_AUIPC => get_arch_pc() + off\n };\n X(rd) = ret;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "bclr", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbs" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << rs2_val[4..0]\n else zero_extend(0b1) << rs2_val[5..0];\n let result : xlenbits = match op {\n RISCV_BCLR => rs1_val & ~(mask),\n RISCV_BEXT => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINV => rs1_val ^ mask,\n RISCV_BSET => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "bclri", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "biop_zbs" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b001010", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << shamt[4..0]\n else zero_extend(0b1) << shamt;\n let result : xlenbits = match op {\n RISCV_BCLRI => rs1_val & ~(mask),\n RISCV_BEXTI => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINVI => rs1_val ^ mask,\n RISCV_BSETI => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "beq", "name": "Conditional Branch", "operands": [ { "name": "imm", "type": "bits(13)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "op", "type": "bop" } ], "syntax": "rs1,rs2,imm", "format": "TBD", "fields": [ { "field": "imm7_6", "size": 1 }, { "field": "imm7_5_0", "size": 6 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_bop(op)", "size": 3 }, { "field": "imm5_4_1", "size": 4 }, { "field": "imm5_0", "size": 1 }, { "field": "0b1100011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let taken : bool = match op {\n RISCV_BEQ => rs1_val == rs2_val,\n RISCV_BNE => rs1_val != rs2_val,\n RISCV_BLT => rs1_val <_s rs2_val,\n RISCV_BGE => rs1_val >=_s rs2_val,\n RISCV_BLTU => rs1_val <_u rs2_val,\n RISCV_BGEU => rs1_val >=_u rs2_val\n };\n let t : xlenbits = PC + sign_extend(imm);\n if taken then {\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL;\n } else {\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n } else RETIRE_SUCCESS\n}", "description": "\nThe target address for this branch instruction is determined by combining\nthe sign-extended 13-bit immediate value with the contents of register rs1.\nAdditionally, the least-significant bit of the result is set to zero.\nThe condition for the branch is based on the specified operation (bop),\nwhich can be one of the following mnemonic codes:\n - \"beq\" : Branch if equal\n - \"bne\" : Branch if not equal\n - \"blt\" : Branch if less than (signed)\n - \"bge\" : Branch if greater than or equal to (signed)\n - \"bltu\" : Branch if less than (unsigned)\n - \"bgeu\" : Branch if greater than or equal to (unsigned)\n *\nThe branch is taken if the specified condition is true, leading to a jump\nto the target address. If the branch is not taken, the execution proceeds\nto the next instruction.\n " }, { "mnemonic": "bext", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbs" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << rs2_val[4..0]\n else zero_extend(0b1) << rs2_val[5..0];\n let result : xlenbits = match op {\n RISCV_BCLR => rs1_val & ~(mask),\n RISCV_BEXT => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINV => rs1_val ^ mask,\n RISCV_BSET => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "bexti", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "biop_zbs" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b001010", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << shamt[4..0]\n else zero_extend(0b1) << shamt;\n let result : xlenbits = match op {\n RISCV_BCLRI => rs1_val & ~(mask),\n RISCV_BEXTI => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINVI => rs1_val ^ mask,\n RISCV_BSETI => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "bge", "name": "Conditional Branch", "operands": [ { "name": "imm", "type": "bits(13)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "op", "type": "bop" } ], "syntax": "rs1,rs2,imm", "format": "TBD", "fields": [ { "field": "imm7_6", "size": 1 }, { "field": "imm7_5_0", "size": 6 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_bop(op)", "size": 3 }, { "field": "imm5_4_1", "size": 4 }, { "field": "imm5_0", "size": 1 }, { "field": "0b1100011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let taken : bool = match op {\n RISCV_BEQ => rs1_val == rs2_val,\n RISCV_BNE => rs1_val != rs2_val,\n RISCV_BLT => rs1_val <_s rs2_val,\n RISCV_BGE => rs1_val >=_s rs2_val,\n RISCV_BLTU => rs1_val <_u rs2_val,\n RISCV_BGEU => rs1_val >=_u rs2_val\n };\n let t : xlenbits = PC + sign_extend(imm);\n if taken then {\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL;\n } else {\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n } else RETIRE_SUCCESS\n}", "description": "\nThe target address for this branch instruction is determined by combining\nthe sign-extended 13-bit immediate value with the contents of register rs1.\nAdditionally, the least-significant bit of the result is set to zero.\nThe condition for the branch is based on the specified operation (bop),\nwhich can be one of the following mnemonic codes:\n - \"beq\" : Branch if equal\n - \"bne\" : Branch if not equal\n - \"blt\" : Branch if less than (signed)\n - \"bge\" : Branch if greater than or equal to (signed)\n - \"bltu\" : Branch if less than (unsigned)\n - \"bgeu\" : Branch if greater than or equal to (unsigned)\n *\nThe branch is taken if the specified condition is true, leading to a jump\nto the target address. If the branch is not taken, the execution proceeds\nto the next instruction.\n " }, { "mnemonic": "bgeu", "name": "Conditional Branch", "operands": [ { "name": "imm", "type": "bits(13)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "op", "type": "bop" } ], "syntax": "rs1,rs2,imm", "format": "TBD", "fields": [ { "field": "imm7_6", "size": 1 }, { "field": "imm7_5_0", "size": 6 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_bop(op)", "size": 3 }, { "field": "imm5_4_1", "size": 4 }, { "field": "imm5_0", "size": 1 }, { "field": "0b1100011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let taken : bool = match op {\n RISCV_BEQ => rs1_val == rs2_val,\n RISCV_BNE => rs1_val != rs2_val,\n RISCV_BLT => rs1_val <_s rs2_val,\n RISCV_BGE => rs1_val >=_s rs2_val,\n RISCV_BLTU => rs1_val <_u rs2_val,\n RISCV_BGEU => rs1_val >=_u rs2_val\n };\n let t : xlenbits = PC + sign_extend(imm);\n if taken then {\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL;\n } else {\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n } else RETIRE_SUCCESS\n}", "description": "\nThe target address for this branch instruction is determined by combining\nthe sign-extended 13-bit immediate value with the contents of register rs1.\nAdditionally, the least-significant bit of the result is set to zero.\nThe condition for the branch is based on the specified operation (bop),\nwhich can be one of the following mnemonic codes:\n - \"beq\" : Branch if equal\n - \"bne\" : Branch if not equal\n - \"blt\" : Branch if less than (signed)\n - \"bge\" : Branch if greater than or equal to (signed)\n - \"bltu\" : Branch if less than (unsigned)\n - \"bgeu\" : Branch if greater than or equal to (unsigned)\n *\nThe branch is taken if the specified condition is true, leading to a jump\nto the target address. If the branch is not taken, the execution proceeds\nto the next instruction.\n " }, { "mnemonic": "binv", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbs" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << rs2_val[4..0]\n else zero_extend(0b1) << rs2_val[5..0];\n let result : xlenbits = match op {\n RISCV_BCLR => rs1_val & ~(mask),\n RISCV_BEXT => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINV => rs1_val ^ mask,\n RISCV_BSET => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "binvi", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "biop_zbs" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b001010", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << shamt[4..0]\n else zero_extend(0b1) << shamt;\n let result : xlenbits = match op {\n RISCV_BCLRI => rs1_val & ~(mask),\n RISCV_BEXTI => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINVI => rs1_val ^ mask,\n RISCV_BSETI => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "blt", "name": "Conditional Branch", "operands": [ { "name": "imm", "type": "bits(13)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "op", "type": "bop" } ], "syntax": "rs1,rs2,imm", "format": "TBD", "fields": [ { "field": "imm7_6", "size": 1 }, { "field": "imm7_5_0", "size": 6 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_bop(op)", "size": 3 }, { "field": "imm5_4_1", "size": 4 }, { "field": "imm5_0", "size": 1 }, { "field": "0b1100011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let taken : bool = match op {\n RISCV_BEQ => rs1_val == rs2_val,\n RISCV_BNE => rs1_val != rs2_val,\n RISCV_BLT => rs1_val <_s rs2_val,\n RISCV_BGE => rs1_val >=_s rs2_val,\n RISCV_BLTU => rs1_val <_u rs2_val,\n RISCV_BGEU => rs1_val >=_u rs2_val\n };\n let t : xlenbits = PC + sign_extend(imm);\n if taken then {\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL;\n } else {\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n } else RETIRE_SUCCESS\n}", "description": "\nThe target address for this branch instruction is determined by combining\nthe sign-extended 13-bit immediate value with the contents of register rs1.\nAdditionally, the least-significant bit of the result is set to zero.\nThe condition for the branch is based on the specified operation (bop),\nwhich can be one of the following mnemonic codes:\n - \"beq\" : Branch if equal\n - \"bne\" : Branch if not equal\n - \"blt\" : Branch if less than (signed)\n - \"bge\" : Branch if greater than or equal to (signed)\n - \"bltu\" : Branch if less than (unsigned)\n - \"bgeu\" : Branch if greater than or equal to (unsigned)\n *\nThe branch is taken if the specified condition is true, leading to a jump\nto the target address. If the branch is not taken, the execution proceeds\nto the next instruction.\n " }, { "mnemonic": "bltu", "name": "Conditional Branch", "operands": [ { "name": "imm", "type": "bits(13)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "op", "type": "bop" } ], "syntax": "rs1,rs2,imm", "format": "TBD", "fields": [ { "field": "imm7_6", "size": 1 }, { "field": "imm7_5_0", "size": 6 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_bop(op)", "size": 3 }, { "field": "imm5_4_1", "size": 4 }, { "field": "imm5_0", "size": 1 }, { "field": "0b1100011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let taken : bool = match op {\n RISCV_BEQ => rs1_val == rs2_val,\n RISCV_BNE => rs1_val != rs2_val,\n RISCV_BLT => rs1_val <_s rs2_val,\n RISCV_BGE => rs1_val >=_s rs2_val,\n RISCV_BLTU => rs1_val <_u rs2_val,\n RISCV_BGEU => rs1_val >=_u rs2_val\n };\n let t : xlenbits = PC + sign_extend(imm);\n if taken then {\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL;\n } else {\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n } else RETIRE_SUCCESS\n}", "description": "\nThe target address for this branch instruction is determined by combining\nthe sign-extended 13-bit immediate value with the contents of register rs1.\nAdditionally, the least-significant bit of the result is set to zero.\nThe condition for the branch is based on the specified operation (bop),\nwhich can be one of the following mnemonic codes:\n - \"beq\" : Branch if equal\n - \"bne\" : Branch if not equal\n - \"blt\" : Branch if less than (signed)\n - \"bge\" : Branch if greater than or equal to (signed)\n - \"bltu\" : Branch if less than (unsigned)\n - \"bgeu\" : Branch if greater than or equal to (unsigned)\n *\nThe branch is taken if the specified condition is true, leading to a jump\nto the target address. If the branch is not taken, the execution proceeds\nto the next instruction.\n " }, { "mnemonic": "bne", "name": "Conditional Branch", "operands": [ { "name": "imm", "type": "bits(13)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "op", "type": "bop" } ], "syntax": "rs1,rs2,imm", "format": "TBD", "fields": [ { "field": "imm7_6", "size": 1 }, { "field": "imm7_5_0", "size": 6 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_bop(op)", "size": 3 }, { "field": "imm5_4_1", "size": 4 }, { "field": "imm5_0", "size": 1 }, { "field": "0b1100011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let taken : bool = match op {\n RISCV_BEQ => rs1_val == rs2_val,\n RISCV_BNE => rs1_val != rs2_val,\n RISCV_BLT => rs1_val <_s rs2_val,\n RISCV_BGE => rs1_val >=_s rs2_val,\n RISCV_BLTU => rs1_val <_u rs2_val,\n RISCV_BGEU => rs1_val >=_u rs2_val\n };\n let t : xlenbits = PC + sign_extend(imm);\n if taken then {\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL;\n } else {\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n } else RETIRE_SUCCESS\n}", "description": "\nThe target address for this branch instruction is determined by combining\nthe sign-extended 13-bit immediate value with the contents of register rs1.\nAdditionally, the least-significant bit of the result is set to zero.\nThe condition for the branch is based on the specified operation (bop),\nwhich can be one of the following mnemonic codes:\n - \"beq\" : Branch if equal\n - \"bne\" : Branch if not equal\n - \"blt\" : Branch if less than (signed)\n - \"bge\" : Branch if greater than or equal to (signed)\n - \"bltu\" : Branch if less than (unsigned)\n - \"bgeu\" : Branch if greater than or equal to (unsigned)\n *\nThe branch is taken if the specified condition is true, leading to a jump\nto the target address. If the branch is not taken, the execution proceeds\nto the next instruction.\n " }, { "mnemonic": "brev8", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011010000111", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen) - 8) by 8)\n result[i+7..i] = reverse(rs1_val[i+7..i]);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "bset", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbs" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << rs2_val[4..0]\n else zero_extend(0b1) << rs2_val[5..0];\n let result : xlenbits = match op {\n RISCV_BCLR => rs1_val & ~(mask),\n RISCV_BEXT => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINV => rs1_val ^ mask,\n RISCV_BSET => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "bseti", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "biop_zbs" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b001010", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbs" ], "function": "{\n let rs1_val = X(rs1);\n let mask : xlenbits = if sizeof(xlen) == 32\n then zero_extend(0b1) << shamt[4..0]\n else zero_extend(0b1) << shamt;\n let result : xlenbits = match op {\n RISCV_BCLRI => rs1_val & ~(mask),\n RISCV_BEXTI => zero_extend(bool_to_bits((rs1_val & mask) != zeros())),\n RISCV_BINVI => rs1_val ^ mask,\n RISCV_BSETI => rs1_val | mask\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "c.add", "name": "TBD", "operands": [ { "name": "rsd", "type": "regidx" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b1", "size": 1 }, { "field": "rsd", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "execute(RTYPE(rs2, rsd, rsd, RISCV_ADD))", "description": "TBD" }, { "mnemonic": "c.add.hint.", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" } ], "syntax": "rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.addi", "name": "TBD", "operands": [ { "name": "nzi", "type": "bits(6)" }, { "name": "rsd", "type": "regidx" } ], "syntax": "rsd,nzi", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "nzi5", "size": 1 }, { "field": "rsd", "size": 5 }, { "field": "nzi40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = sign_extend(nzi);\n execute(ITYPE(imm, rsd, rsd, RISCV_ADDI))\n}", "description": "TBD" }, { "mnemonic": "c.addi.hint.", "name": "TBD", "operands": [ { "name": "rsd", "type": "regidx" } ], "syntax": "rsd", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "rsd", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.addi16sp", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" } ], "syntax": "imm", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "nzi9", "size": 1 }, { "field": "0b00010", "size": 5 }, { "field": "nzi4", "size": 1 }, { "field": "nzi6", "size": 1 }, { "field": "nzi87", "size": 2 }, { "field": "nzi5", "size": 1 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = sign_extend(imm @ 0x0);\n execute(ITYPE(imm, sp, sp, RISCV_ADDI))\n}", "description": "TBD" }, { "mnemonic": "c.addi4spn", "name": "TBD", "operands": [ { "name": "rdc", "type": "cregidx" }, { "name": "nzimm", "type": "bits(8)" } ], "syntax": "rdc,nzimm,0b00", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "nz54", "size": 2 }, { "field": "nz96", "size": 4 }, { "field": "nz2", "size": 1 }, { "field": "nz3", "size": 1 }, { "field": "rd", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = (0b00 @ nzimm @ 0b00);\n let rd = creg2reg_idx(rdc);\n execute(ITYPE(imm, sp, rd, RISCV_ADDI))\n}", "description": "TBD" }, { "mnemonic": "c.addiw", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" }, { "name": "rsd", "type": "regidx" } ], "syntax": "rsd,imm", "format": "TBD", "fields": [ { "field": "0b001", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "rsd", "size": 5 }, { "field": "imm40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "execute(ADDIW(sign_extend(imm), rsd, rsd))", "description": "TBD" }, { "mnemonic": "c.addw", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" }, { "name": "rs2", "type": "cregidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b1", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b01", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n let rs2 = creg2reg_idx(rs2);\n execute(RTYPEW(rs2, rsd, rsd, RISCV_ADDW))\n}", "description": "TBD" }, { "mnemonic": "c.and", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" }, { "name": "rs2", "type": "cregidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b11", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n let rs2 = creg2reg_idx(rs2);\n execute(RTYPE(rs2, rsd, rsd, RISCV_AND))\n}", "description": "TBD" }, { "mnemonic": "c.andi", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" }, { "name": "rsd", "type": "cregidx" } ], "syntax": "rsd,imm", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "i5", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "i40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n execute(ITYPE(sign_extend(imm), rsd, rsd, RISCV_ANDI))\n}", "description": "TBD" }, { "mnemonic": "c.beqz", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(8)" }, { "name": "rs", "type": "cregidx" } ], "syntax": "rs,imm", "format": "TBD", "fields": [ { "field": "0b110", "size": 3 }, { "field": "i8", "size": 1 }, { "field": "i43", "size": 2 }, { "field": "rs", "size": 3 }, { "field": "i76", "size": 2 }, { "field": "i21", "size": 2 }, { "field": "i5", "size": 1 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "execute(BTYPE(sign_extend(imm @ 0b0), zreg, creg2reg_idx(rs), RISCV_BEQ))", "description": "TBD" }, { "mnemonic": "c.bnez", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(8)" }, { "name": "rs", "type": "cregidx" } ], "syntax": "rs,imm", "format": "TBD", "fields": [ { "field": "0b111", "size": 3 }, { "field": "i8", "size": 1 }, { "field": "i43", "size": 2 }, { "field": "rs", "size": 3 }, { "field": "i76", "size": 2 }, { "field": "i21", "size": 2 }, { "field": "i5", "size": 1 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "execute(BTYPE(sign_extend(imm @ 0b0), zreg, creg2reg_idx(rs), RISCV_BNE))", "description": "TBD" }, { "mnemonic": "c.ebreak", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "execute(EBREAK())", "description": "TBD" }, { "mnemonic": "c.fld", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc", "type": "cregidx" }, { "name": "rdc", "type": "cregidx" } ], "syntax": "rdc,rsc,uimm,0b000", "format": "TBD", "fields": [ { "field": "0b001", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui76", "size": 2 }, { "field": "rd", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C", "D" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n let rd = creg2reg_idx(rdc);\n let rs = creg2reg_idx(rsc);\n execute(LOAD_FP(imm, rs, rd, DOUBLE))\n}", "description": "TBD" }, { "mnemonic": "c.fldsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,uimm", "format": "TBD", "fields": [ { "field": "0b001", "size": 3 }, { "field": "ui5", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "ui43", "size": 2 }, { "field": "ui86", "size": 3 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C", "D" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n execute(LOAD_FP(imm, sp, rd, DOUBLE))\n}", "description": "TBD" }, { "mnemonic": "c.flw", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc", "type": "cregidx" }, { "name": "rdc", "type": "cregidx" } ], "syntax": "rdc,rsc,uimm,0b00", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui2", "size": 1 }, { "field": "ui6", "size": 1 }, { "field": "rd", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C", "F" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n let rd = creg2reg_idx(rdc);\n let rs = creg2reg_idx(rsc);\n execute(LOAD_FP(imm, rs, rd, WORD))\n}", "description": "TBD" }, { "mnemonic": "c.flwsp", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,imm", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "ui5", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "ui42", "size": 3 }, { "field": "ui76", "size": 2 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C", "F" ], "function": "{\n let imm : bits(12) = zero_extend(imm @ 0b00);\n execute(LOAD_FP(imm, sp, rd, WORD))\n}", "description": "TBD" }, { "mnemonic": "c.fsd", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc1", "type": "cregidx" }, { "name": "rsc2", "type": "cregidx" } ], "syntax": "rsc1,rsc2,uimm,0b000", "format": "TBD", "fields": [ { "field": "0b101", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui76", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C", "D" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n let rs1 = creg2reg_idx(rsc1);\n let rs2 = creg2reg_idx(rsc2);\n execute(STORE_FP(imm, rs2, rs1, DOUBLE))\n}", "description": "TBD" }, { "mnemonic": "c.fsdsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rs2,uimm", "format": "TBD", "fields": [ { "field": "0b101", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "ui86", "size": 3 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C", "D" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n execute(STORE_FP(imm, rs2, sp, DOUBLE))\n}", "description": "TBD" }, { "mnemonic": "c.fsw", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc1", "type": "cregidx" }, { "name": "rsc2", "type": "cregidx" } ], "syntax": "rsc1,rsc2,uimm,0b00", "format": "TBD", "fields": [ { "field": "0b111", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui2", "size": 1 }, { "field": "ui6", "size": 1 }, { "field": "rs2", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C", "F" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n let rs1 = creg2reg_idx(rsc1);\n let rs2 = creg2reg_idx(rsc2);\n execute(STORE_FP(imm, rs2, rs1, WORD))\n}", "description": "TBD" }, { "mnemonic": "c.fswsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rs2,uimm", "format": "TBD", "fields": [ { "field": "0b111", "size": 3 }, { "field": "ui52", "size": 4 }, { "field": "ui76", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C", "F" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n execute(STORE_FP(imm, rs2, sp, WORD))\n}", "description": "TBD" }, { "mnemonic": "c.illegal", "name": "TBD", "operands": [ { "name": "s", "type": "half" } ], "syntax": "s", "format": "TBD", "fields": [ { "field": "s", "size": 16 } ], "extensions": [], "function": "{ handle_illegal(); RETIRE_FAIL }", "description": "TBD" }, { "mnemonic": "c.j", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(11)" } ], "syntax": "imm", "format": "TBD", "fields": [ { "field": "0b101", "size": 3 }, { "field": "i11", "size": 1 }, { "field": "i4", "size": 1 }, { "field": "i98", "size": 2 }, { "field": "i10", "size": 1 }, { "field": "i6", "size": 1 }, { "field": "i7", "size": 1 }, { "field": "i31", "size": 3 }, { "field": "i5", "size": 1 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "execute(RISCV_JAL(sign_extend(imm @ 0b0), zreg))", "description": "TBD" }, { "mnemonic": "c.jal", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(11)" } ], "syntax": "imm,0b0", "format": "TBD", "fields": [ { "field": "0b001", "size": 3 }, { "field": "i11", "size": 1 }, { "field": "i4", "size": 1 }, { "field": "i98", "size": 2 }, { "field": "i10", "size": 1 }, { "field": "i6", "size": 1 }, { "field": "i7", "size": 1 }, { "field": "i31", "size": 3 }, { "field": "i5", "size": 1 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "execute(RISCV_JAL(sign_extend(imm @ 0b0), ra))", "description": "TBD" }, { "mnemonic": "c.jalr", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" } ], "syntax": "rs1", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b1", "size": 1 }, { "field": "rs1", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "execute(RISCV_JALR(zero_extend(0b0), rs1, ra))", "description": "TBD" }, { "mnemonic": "c.jr", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" } ], "syntax": "rs1", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "rs1", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "execute(RISCV_JALR(zero_extend(0b0), rs1, zreg))", "description": "TBD" }, { "mnemonic": "c.ld", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc", "type": "cregidx" }, { "name": "rdc", "type": "cregidx" } ], "syntax": "rdc,rsc,uimm,0b000", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui76", "size": 2 }, { "field": "rd", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n let rd = creg2reg_idx(rdc);\n let rs = creg2reg_idx(rsc);\n execute(LOAD(imm, rs, rd, false, DOUBLE, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.ldsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,uimm", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "ui5", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "ui43", "size": 2 }, { "field": "ui86", "size": 3 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n execute(LOAD(imm, sp, rd, false, DOUBLE, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.li", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,imm", "format": "TBD", "fields": [ { "field": "0b010", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "imm40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = sign_extend(imm);\n execute(ITYPE(imm, zreg, rd, RISCV_ADDI))\n}", "description": "TBD" }, { "mnemonic": "c.li.hint.", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" } ], "syntax": "imm", "format": "TBD", "fields": [ { "field": "0b010", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "imm40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.lui", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,imm", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "imm17", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "imm1612", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let res : bits(20) = sign_extend(imm);\n execute(UTYPE(res, rd, RISCV_LUI))\n}", "description": "TBD" }, { "mnemonic": "c.lui.hint.", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" } ], "syntax": "imm", "format": "TBD", "fields": [ { "field": "0b011", "size": 3 }, { "field": "imm17", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "imm1612", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.lw", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc", "type": "cregidx" }, { "name": "rdc", "type": "cregidx" } ], "syntax": "rdc,rsc,uimm,0b00", "format": "TBD", "fields": [ { "field": "0b010", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui2", "size": 1 }, { "field": "ui6", "size": 1 }, { "field": "rd", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n let rd = creg2reg_idx(rdc);\n let rs = creg2reg_idx(rsc);\n execute(LOAD(imm, rs, rd, false, WORD, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.lwsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,uimm", "format": "TBD", "fields": [ { "field": "0b010", "size": 3 }, { "field": "ui5", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "ui42", "size": 3 }, { "field": "ui76", "size": 2 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n execute(LOAD(imm, sp, rd, false, WORD, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.mv", "name": "TBD", "operands": [ { "name": "rd", "type": "regidx" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "execute(RTYPE(rs2, zreg, rd, RISCV_ADD))", "description": "TBD" }, { "mnemonic": "c.mv.hint.", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" } ], "syntax": "rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.nop", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.nop.hint.", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(6)" } ], "syntax": "imm", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "im5", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "im40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.or", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" }, { "name": "rs2", "type": "cregidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b10", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n let rs2 = creg2reg_idx(rs2);\n execute(RTYPE(rs2, rsd, rsd, RISCV_OR))\n}", "description": "TBD" }, { "mnemonic": "c.sd", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc1", "type": "cregidx" }, { "name": "rsc2", "type": "cregidx" } ], "syntax": "rsc1,rsc2,uimm,0b000", "format": "TBD", "fields": [ { "field": "0b111", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui76", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n let rs1 = creg2reg_idx(rsc1);\n let rs2 = creg2reg_idx(rsc2);\n execute(STORE(imm, rs2, rs1, DOUBLE, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.sdsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rs2,uimm", "format": "TBD", "fields": [ { "field": "0b111", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "ui86", "size": 3 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b000);\n execute(STORE(imm, rs2, sp, DOUBLE, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.slli", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rsd", "type": "regidx" } ], "syntax": "rsd,shamt", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "nzui5", "size": 1 }, { "field": "rsd", "size": 5 }, { "field": "nzui40", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "execute(SHIFTIOP(shamt, rsd, rsd, RISCV_SLLI))", "description": "TBD" }, { "mnemonic": "c.slli.hint.", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rsd", "type": "regidx" } ], "syntax": "rsd,shamt", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "nzui5", "size": 1 }, { "field": "rsd", "size": 5 }, { "field": "nzui40", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.srai", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rsd", "type": "cregidx" } ], "syntax": "rsd,shamt", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "nzui5", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "nzui40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n execute(SHIFTIOP(shamt, rsd, rsd, RISCV_SRAI))\n}", "description": "TBD" }, { "mnemonic": "c.srai.hint.", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" } ], "syntax": "rsd", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.srli", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rsd", "type": "cregidx" } ], "syntax": "rsd,shamt", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "nzui5", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "nzui40", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n execute(SHIFTIOP(shamt, rsd, rsd, RISCV_SRLI))\n}", "description": "TBD" }, { "mnemonic": "c.srli.hint.", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" } ], "syntax": "rsd", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b01", "size": 2 } ], "extensions": [], "function": "RETIRE_SUCCESS", "description": "TBD" }, { "mnemonic": "c.sub", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" }, { "name": "rs2", "type": "cregidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b00", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n let rs2 = creg2reg_idx(rs2);\n execute(RTYPE(rs2, rsd, rsd, RISCV_SUB))\n}", "description": "TBD" }, { "mnemonic": "c.subw", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" }, { "name": "rs2", "type": "cregidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b1", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b00", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n let rs2 = creg2reg_idx(rs2);\n execute(RTYPEW(rs2, rsd, rsd, RISCV_SUBW))\n}", "description": "TBD" }, { "mnemonic": "c.sw", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(5)" }, { "name": "rsc1", "type": "cregidx" }, { "name": "rsc2", "type": "cregidx" } ], "syntax": "rsc1,rsc2,uimm,0b00", "format": "TBD", "fields": [ { "field": "0b110", "size": 3 }, { "field": "ui53", "size": 3 }, { "field": "rs1", "size": 3 }, { "field": "ui2", "size": 1 }, { "field": "ui6", "size": 1 }, { "field": "rs2", "size": 3 }, { "field": "0b00", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n let rs1 = creg2reg_idx(rsc1);\n let rs2 = creg2reg_idx(rsc2);\n execute(STORE(imm, rs2, rs1, WORD, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.swsp", "name": "TBD", "operands": [ { "name": "uimm", "type": "bits(6)" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rs2,uimm", "format": "TBD", "fields": [ { "field": "0b110", "size": 3 }, { "field": "ui52", "size": 4 }, { "field": "ui76", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "0b10", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let imm : bits(12) = zero_extend(uimm @ 0b00);\n execute(STORE(imm, rs2, sp, WORD, false, false))\n}", "description": "TBD" }, { "mnemonic": "c.xor", "name": "TBD", "operands": [ { "name": "rsd", "type": "cregidx" }, { "name": "rs2", "type": "cregidx" } ], "syntax": "rsd,rs2", "format": "TBD", "fields": [ { "field": "0b100", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "rsd", "size": 3 }, { "field": "0b01", "size": 2 }, { "field": "rs2", "size": 3 }, { "field": "0b01", "size": 2 } ], "extensions": [ "C" ], "function": "{\n let rsd = creg2reg_idx(rsd);\n let rs2 = creg2reg_idx(rs2);\n execute(RTYPE(rs2, rsd, rsd, RISCV_XOR))\n}", "description": "TBD" }, { "mnemonic": "clmul", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbc", "Zbkc" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n result : xlenbits = zeros();\n foreach (i from 0 to (xlen_val - 1))\n if rs2_val[i] == bitone then result = result ^ (rs1_val << i);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "clmulh", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbc", "Zbkc" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n result : xlenbits = zeros();\n foreach (i from 0 to (xlen_val - 1))\n if rs2_val[i] == bitone then result = result ^ (rs1_val >> (xlen_val - i));\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "clmulr", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbc" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n result : xlenbits = zeros();\n foreach (i from 0 to (xlen_val - 1))\n if rs2_val[i] == bitone then result = result ^ (rs1_val >> (xlen_val - i - 1));\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "clz", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011000000000", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : nat = 0;\n done : bool = false;\n foreach (i from (sizeof(xlen) - 1) downto 0)\n if not(done) then if rs1_val[i] == bitzero\n then result = result + 1\n else done = true;\n X(rd) = to_bits(sizeof(xlen), result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "clzw", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011000000000", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : nat = 0;\n done : bool = false;\n foreach (i from 31 downto 0)\n if not(done) then if rs1_val[i] == bitzero\n then result = result + 1\n else done = true;\n X(rd) = to_bits(sizeof(xlen), result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "cpop", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011000000010", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : nat = 0;\n foreach (i from 0 to (xlen_val - 1))\n if rs1_val[i] == bitone then result = result + 1;\n X(rd) = to_bits(sizeof(xlen), result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "cpopw", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011000000010", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : nat = 0;\n foreach (i from 0 to 31)\n if rs1_val[i] == bitone then result = result + 1;\n X(rd) = to_bits(sizeof(xlen), result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "csrrc", "name": "TBD", "operands": [ { "name": "csr", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_imm", "type": "bool" }, { "name": "op", "type": "csrop" } ], "syntax": "rd,csr,rs1", "format": "TBD", "fields": [ { "field": "csr", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_imm)", "size": 1 }, { "field": "encdec_csrop(op)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val : xlenbits = if is_imm then zero_extend(rs1) else X(rs1);\n let isWrite : bool = match op {\n CSRRW => true,\n _ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0\n };\n if not(check_CSR(csr, cur_privilege, isWrite))\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_CSR(csr, cur_privilege, isWrite))\n then { ext_check_CSR_fail(); RETIRE_FAIL }\n else {\n let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */\n if isWrite then {\n let new_val : xlenbits = match op {\n CSRRW => rs1_val,\n CSRRS => csr_val | rs1_val,\n CSRRC => csr_val & ~(rs1_val)\n };\n writeCSR(csr, new_val)\n };\n X(rd) = csr_val;\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "csrrci", "name": "TBD", "operands": [ { "name": "csr", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_imm", "type": "bool" }, { "name": "op", "type": "csrop" } ], "syntax": "rd,csr,rs1", "format": "TBD", "fields": [ { "field": "csr", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_imm)", "size": 1 }, { "field": "encdec_csrop(op)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val : xlenbits = if is_imm then zero_extend(rs1) else X(rs1);\n let isWrite : bool = match op {\n CSRRW => true,\n _ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0\n };\n if not(check_CSR(csr, cur_privilege, isWrite))\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_CSR(csr, cur_privilege, isWrite))\n then { ext_check_CSR_fail(); RETIRE_FAIL }\n else {\n let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */\n if isWrite then {\n let new_val : xlenbits = match op {\n CSRRW => rs1_val,\n CSRRS => csr_val | rs1_val,\n CSRRC => csr_val & ~(rs1_val)\n };\n writeCSR(csr, new_val)\n };\n X(rd) = csr_val;\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "csrrs", "name": "TBD", "operands": [ { "name": "csr", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_imm", "type": "bool" }, { "name": "op", "type": "csrop" } ], "syntax": "rd,csr,rs1", "format": "TBD", "fields": [ { "field": "csr", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_imm)", "size": 1 }, { "field": "encdec_csrop(op)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val : xlenbits = if is_imm then zero_extend(rs1) else X(rs1);\n let isWrite : bool = match op {\n CSRRW => true,\n _ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0\n };\n if not(check_CSR(csr, cur_privilege, isWrite))\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_CSR(csr, cur_privilege, isWrite))\n then { ext_check_CSR_fail(); RETIRE_FAIL }\n else {\n let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */\n if isWrite then {\n let new_val : xlenbits = match op {\n CSRRW => rs1_val,\n CSRRS => csr_val | rs1_val,\n CSRRC => csr_val & ~(rs1_val)\n };\n writeCSR(csr, new_val)\n };\n X(rd) = csr_val;\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "csrrsi", "name": "TBD", "operands": [ { "name": "csr", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_imm", "type": "bool" }, { "name": "op", "type": "csrop" } ], "syntax": "rd,csr,rs1", "format": "TBD", "fields": [ { "field": "csr", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_imm)", "size": 1 }, { "field": "encdec_csrop(op)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val : xlenbits = if is_imm then zero_extend(rs1) else X(rs1);\n let isWrite : bool = match op {\n CSRRW => true,\n _ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0\n };\n if not(check_CSR(csr, cur_privilege, isWrite))\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_CSR(csr, cur_privilege, isWrite))\n then { ext_check_CSR_fail(); RETIRE_FAIL }\n else {\n let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */\n if isWrite then {\n let new_val : xlenbits = match op {\n CSRRW => rs1_val,\n CSRRS => csr_val | rs1_val,\n CSRRC => csr_val & ~(rs1_val)\n };\n writeCSR(csr, new_val)\n };\n X(rd) = csr_val;\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "csrrw", "name": "TBD", "operands": [ { "name": "csr", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_imm", "type": "bool" }, { "name": "op", "type": "csrop" } ], "syntax": "rd,csr,rs1", "format": "TBD", "fields": [ { "field": "csr", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_imm)", "size": 1 }, { "field": "encdec_csrop(op)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val : xlenbits = if is_imm then zero_extend(rs1) else X(rs1);\n let isWrite : bool = match op {\n CSRRW => true,\n _ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0\n };\n if not(check_CSR(csr, cur_privilege, isWrite))\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_CSR(csr, cur_privilege, isWrite))\n then { ext_check_CSR_fail(); RETIRE_FAIL }\n else {\n let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */\n if isWrite then {\n let new_val : xlenbits = match op {\n CSRRW => rs1_val,\n CSRRS => csr_val | rs1_val,\n CSRRC => csr_val & ~(rs1_val)\n };\n writeCSR(csr, new_val)\n };\n X(rd) = csr_val;\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "csrrwi", "name": "TBD", "operands": [ { "name": "csr", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_imm", "type": "bool" }, { "name": "op", "type": "csrop" } ], "syntax": "rd,csr,rs1", "format": "TBD", "fields": [ { "field": "csr", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_imm)", "size": 1 }, { "field": "encdec_csrop(op)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val : xlenbits = if is_imm then zero_extend(rs1) else X(rs1);\n let isWrite : bool = match op {\n CSRRW => true,\n _ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0\n };\n if not(check_CSR(csr, cur_privilege, isWrite))\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_CSR(csr, cur_privilege, isWrite))\n then { ext_check_CSR_fail(); RETIRE_FAIL }\n else {\n let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */\n if isWrite then {\n let new_val : xlenbits = match op {\n CSRRW => rs1_val,\n CSRRS => csr_val | rs1_val,\n CSRRC => csr_val & ~(rs1_val)\n };\n writeCSR(csr, new_val)\n };\n X(rd) = csr_val;\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "ctz", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011000000001", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : nat = 0;\n done : bool = false;\n foreach (i from 0 to (sizeof(xlen) - 1))\n if not(done) then if rs1_val[i] == bitzero\n then result = result + 1\n else done = true;\n X(rd) = to_bits(sizeof(xlen), result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "ctzw", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011000000001", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : nat = 0;\n done : bool = false;\n foreach (i from 0 to 31)\n if not(done) then if rs1_val[i] == bitzero\n then result = result + 1\n else done = true;\n X(rd) = to_bits(sizeof(xlen), result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "czero.eqz", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "RISCV_CZERO_NEZ", "type": "zicondop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000111", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zicond" ], "function": "{\n let value = X(rs1);\n let condition = X(rs2);\n let result : xlenbits = if (condition != zeros()) then zeros()\n\t\t\t\t\t\t else value;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "czero.nez", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "RISCV_CZERO_NEZ", "type": "zicondop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000111", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zicond" ], "function": "{\n let value = X(rs1);\n let condition = X(rs2);\n let result : xlenbits = if (condition != zeros()) then zeros()\n\t\t\t\t\t\t else value;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "div", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let q : int = if rs2_int == 0 then -1 else quot_round_zero(rs1_int, rs2_int);\n /* check for signed overflow */\n let q': int = if s & q > xlen_max_signed then xlen_min_signed else q;\n X(rd) = to_bits(sizeof(xlen), q');\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "divu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let q : int = if rs2_int == 0 then -1 else quot_round_zero(rs1_int, rs2_int);\n /* check for signed overflow */\n let q': int = if s & q > xlen_max_signed then xlen_min_signed else q;\n X(rd) = to_bits(sizeof(xlen), q');\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "divuw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1)[31..0];\n let rs2_val = X(rs2)[31..0];\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let q : int = if rs2_int == 0 then -1 else quot_round_zero(rs1_int, rs2_int);\n /* check for signed overflow */\n let q': int = if s & q > (2 ^ 31 - 1) then (0 - 2^31) else q;\n X(rd) = sign_extend(to_bits(32, q'));\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "divw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1)[31..0];\n let rs2_val = X(rs2)[31..0];\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let q : int = if rs2_int == 0 then -1 else quot_round_zero(rs1_int, rs2_int);\n /* check for signed overflow */\n let q': int = if s & q > (2 ^ 31 - 1) then (0 - 2^31) else q;\n X(rd) = sign_extend(to_bits(32, q'));\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "ebreak", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b000000000001", "size": 12 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n handle_mem_exception(PC, E_Breakpoint());\n RETIRE_FAIL\n}", "description": "TBD" }, { "mnemonic": "ecall", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b000000000000", "size": 12 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let t : sync_exception =\n struct { trap = match (cur_privilege) {\n User => E_U_EnvCall(),\n Supervisor => E_S_EnvCall(),\n Machine => E_M_EnvCall()\n },\n excinfo = (None() : option(xlenbits)),\n ext = None() };\n set_next_pc(exception_handler(cur_privilege, CTL_TRAP(t), PC));\n RETIRE_FAIL\n}", "description": "TBD" }, { "mnemonic": "fadd.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_D" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) = match op {\n FADD_D => riscv_f64Add (rm_3b, rs1_val_64b, rs2_val_64b),\n FSUB_D => riscv_f64Sub (rm_3b, rs1_val_64b, rs2_val_64b),\n FMUL_D => riscv_f64Mul (rm_3b, rs1_val_64b, rs2_val_64b),\n FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fadd.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_H" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001110", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) = match op {\n FADD_H => riscv_f16Add (rm_3b, rs1_val_16b, rs2_val_16b),\n FSUB_H => riscv_f16Sub (rm_3b, rs1_val_16b, rs2_val_16b),\n FMUL_H => riscv_f16Mul (rm_3b, rs1_val_16b, rs2_val_16b),\n FDIV_H => riscv_f16Div (rm_3b, rs1_val_16b, rs2_val_16b)\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fadd.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_S" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) = match op {\n FADD_S => riscv_f32Add (rm_3b, rs1_val_32b, rs2_val_32b),\n FSUB_S => riscv_f32Sub (rm_3b, rs1_val_32b, rs2_val_32b),\n FMUL_S => riscv_f32Mul (rm_3b, rs1_val_32b, rs2_val_32b),\n FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fclass.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_D_X", "type": "f_un_op_D" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111001", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D" ], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_X = X(rs1);\n let rd_val_D = rs1_val_X [63..0];\n F(rd) = rd_val_D;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fclass.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_H_X", "type": "f_un_op_H" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111010", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh" ], "function": "{\n let rs1_val_X = X(rs1);\n let rd_val_H = rs1_val_X [15..0];\n F(rd) = nan_box (rd_val_H);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fclass.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_W_X", "type": "f_un_op_S" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111000", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "F" ], "function": "{\n let rs1_val_X = X(rs1);\n let rd_val_S = rs1_val_X [31..0];\n F(rd) = nan_box (rd_val_S);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fcvt.d.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.d.l", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.d.lu", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.d.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.d.w", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.d.wu", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.h.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.h.l", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.h.lu", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.h.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.h.w", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.h.wu", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.l.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.l.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.l.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.lu.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.lu.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.lu.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.s.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.s.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.s.l", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.s.lu", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.s.w", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.s.wu", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.w.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.w.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.w.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.wu.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.wu.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvt.wu.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fcvtmod.w.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1100001", "size": 7 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F_D(rs1);\n let (fflags, rd_val) = fcvtmod_helper(rs1_val_D);\n accrue_fflags(fflags);\n X(rd) = sign_extend(rd_val);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fdiv.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_D" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) = match op {\n FADD_D => riscv_f64Add (rm_3b, rs1_val_64b, rs2_val_64b),\n FSUB_D => riscv_f64Sub (rm_3b, rs1_val_64b, rs2_val_64b),\n FMUL_D => riscv_f64Mul (rm_3b, rs1_val_64b, rs2_val_64b),\n FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fdiv.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_H" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001110", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) = match op {\n FADD_H => riscv_f16Add (rm_3b, rs1_val_16b, rs2_val_16b),\n FSUB_H => riscv_f16Sub (rm_3b, rs1_val_16b, rs2_val_16b),\n FMUL_H => riscv_f16Mul (rm_3b, rs1_val_16b, rs2_val_16b),\n FDIV_H => riscv_f16Div (rm_3b, rs1_val_16b, rs2_val_16b)\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fdiv.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_S" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) = match op {\n FADD_S => riscv_f32Add (rm_3b, rs1_val_32b, rs2_val_32b),\n FSUB_S => riscv_f32Sub (rm_3b, rs1_val_32b, rs2_val_32b),\n FMUL_S => riscv_f32Mul (rm_3b, rs1_val_32b, rs2_val_32b),\n FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fence", "name": "Fence (Memory)", "operands": [ { "name": "pred", "type": "bits(4)" }, { "name": "succ", "type": "bits(4)" } ], "syntax": "pred,succ", "format": "I", "fields": [ { "field": "0b0000", "size": 4 }, { "field": "pred", "size": 4 }, { "field": "succ", "size": 4 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b0001111", "size": 7 } ], "extensions": [], "function": "{\n // If the FIOM bit in menvcfg/senvcfg is set then the I/O bits can imply R/W.\n let fiom = is_fiom_active();\n let pred = effective_fence_set(pred, fiom);\n let succ = effective_fence_set(succ, fiom);\n\n match (pred, succ) {\n (_ : bits(2) @ 0b11, _ : bits(2) @ 0b11) => __barrier(Barrier_RISCV_rw_rw()),\n (_ : bits(2) @ 0b10, _ : bits(2) @ 0b11) => __barrier(Barrier_RISCV_r_rw()),\n (_ : bits(2) @ 0b10, _ : bits(2) @ 0b10) => __barrier(Barrier_RISCV_r_r()),\n (_ : bits(2) @ 0b11, _ : bits(2) @ 0b01) => __barrier(Barrier_RISCV_rw_w()),\n (_ : bits(2) @ 0b01, _ : bits(2) @ 0b01) => __barrier(Barrier_RISCV_w_w()),\n (_ : bits(2) @ 0b01, _ : bits(2) @ 0b11) => __barrier(Barrier_RISCV_w_rw()),\n (_ : bits(2) @ 0b11, _ : bits(2) @ 0b10) => __barrier(Barrier_RISCV_rw_r()),\n (_ : bits(2) @ 0b10, _ : bits(2) @ 0b01) => __barrier(Barrier_RISCV_r_w()),\n (_ : bits(2) @ 0b01, _ : bits(2) @ 0b10) => __barrier(Barrier_RISCV_w_r()),\n\n (_ : bits(4) , _ : bits(2) @ 0b00) => (),\n (_ : bits(2) @ 0b00, _ : bits(4) ) => (),\n\n _ => { print(\"FIXME: unsupported fence\");\n () }\n };\n RETIRE_SUCCESS\n}", "description": "\nThe FENCE instruction is used to provide memory ordering guarantees.\nIt specifies ordering constraints on memory operations that precede\nand follow it in program order. The FENCE instruction includes two\n4-bit fields, 'pred' and 'succ', which represent the memory ordering\nrequirements before and after the FENCE instruction, respectively.\n *\nThe bits in 'pred' and 'succ' represent the following ordering constraints:\n- 'i': instruction stream order\n- 'o': outstanding loads\n- 'r': read operations\n- 'w': write operations\n *\nThe FENCE instruction is used to control the visibility of memory\noperations, and its behavior is influenced by the 'pred' and 'succ'\nfields. The precise semantics of the FENCE instruction depend on the\nspecific bits set in these fields.\n " }, { "mnemonic": "fence.i", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b000000000000", "size": 12 }, { "field": "0b00000", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b0001111", "size": 7 } ], "extensions": [], "function": "{ /* __barrier(Barrier_RISCV_i); */ RETIRE_SUCCESS }", "description": "TBD" }, { "mnemonic": "fence.tso", "name": "Fence (Total Store Order)", "operands": [ { "name": "pred", "type": "bits(4)" }, { "name": "succ", "type": "bits(4)" } ], "syntax": "pred,succ", "format": "I", "fields": [ { "field": "0b1000", "size": 4 }, { "field": "pred", "size": 4 }, { "field": "succ", "size": 4 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b0001111", "size": 7 } ], "extensions": [], "function": "{\n match (pred, succ) {\n (_ : bits(2) @ 0b11, _ : bits(2) @ 0b11) => __barrier(Barrier_RISCV_tso()),\n (_ : bits(2) @ 0b00, _ : bits(2) @ 0b00) => (),\n\n _ => { print(\"FIXME: unsupported fence\");\n () }\n };\n RETIRE_SUCCESS\n}", "description": "\nThe FENCE_TSO instruction is a memory\nordering instruction that provides a stronger memory consistency model\ncompared to the standard FENCE instruction. It ensures that all memory\noperations preceding and following the FENCE_TSO instruction are globally\nordered. The FENCE_TSO instruction includes two 4-bit fields, 'pred' and\n'succ', which represent the memory ordering requirements before and after\nthe FENCE_TSO instruction, respectively.\n " }, { "mnemonic": "feq.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "feq.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "feq.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "flb", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let (aq, rl, res) = (false, false, false);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF =>\n process_fload16(rd, vaddr, mem_read(Read(Data), addr, 2, aq, rl, res)),\n WORD =>\n process_fload32(rd, vaddr, mem_read(Read(Data), addr, 4, aq, rl, res)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fload64(rd, vaddr, mem_read(Read(Data), addr, 8, aq, rl, res)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point load\"),\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fld", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let (aq, rl, res) = (false, false, false);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF =>\n process_fload16(rd, vaddr, mem_read(Read(Data), addr, 2, aq, rl, res)),\n WORD =>\n process_fload32(rd, vaddr, mem_read(Read(Data), addr, 4, aq, rl, res)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fload64(rd, vaddr, mem_read(Read(Data), addr, 8, aq, rl, res)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point load\"),\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fle.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fle.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fle.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fleq.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F_D(rs1);\n let rs2_val_D = F_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le_quiet (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fleq.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let rs1_val_H = F_H(rs1);\n let rs2_val_H = F_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le_quiet (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fleq.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let rs1_val_S = F_S(rs1);\n let rs2_val_S = F_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le_quiet (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "flh", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let (aq, rl, res) = (false, false, false);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF =>\n process_fload16(rd, vaddr, mem_read(Read(Data), addr, 2, aq, rl, res)),\n WORD =>\n process_fload32(rd, vaddr, mem_read(Read(Data), addr, 4, aq, rl, res)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fload64(rd, vaddr, mem_read(Read(Data), addr, 8, aq, rl, res)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point load\"),\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fli.d", "name": "TBD", "operands": [ { "name": "constantidx", "type": "bits(5)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,constantidx", "format": "TBD", "fields": [ { "field": "0b1111001", "size": 7 }, { "field": "0b00001", "size": 5 }, { "field": "rs1", "size": 3 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let bits : bits(64) = match constantidx {\n 0b00000 => { 0xbff0000000000000 }, /* -1.0 */\n 0b00001 => { 0x0010000000000000 }, /* minimum positive normal */\n 0b00010 => { 0x3Ef0000000000000 }, /* 1.0 * 2^-16 */\n 0b00011 => { 0x3f00000000000000 }, /* 1.0 * 2^-15 */\n 0b00100 => { 0x3f70000000000000 }, /* 1.0 * 2^-8 */\n 0b00101 => { 0x3f80000000000000 }, /* 1.0 * 2^-7 */\n 0b00110 => { 0x3fb0000000000000 }, /* 1.0 * 2^-4 */\n 0b00111 => { 0x3fc0000000000000 }, /* 1.0 * 2^-3 */\n 0b01000 => { 0x3fd0000000000000 }, /* 0.25 */\n 0b01001 => { 0x3fd4000000000000 }, /* 0.3125 */\n 0b01010 => { 0x3fd8000000000000 }, /* 0.375 */\n 0b01011 => { 0x3fdc000000000000 }, /* 0.4375 */\n 0b01100 => { 0x3fe0000000000000 }, /* 0.5 */\n 0b01101 => { 0x3fe4000000000000 }, /* 0.625 */\n 0b01110 => { 0x3fe8000000000000 }, /* 0.75 */\n 0b01111 => { 0x3fec000000000000 }, /* 0.875 */\n 0b10000 => { 0x3ff0000000000000 }, /* 1.0 */\n 0b10001 => { 0x3ff4000000000000 }, /* 1.25 */\n 0b10010 => { 0x3ff8000000000000 }, /* 1.5 */\n 0b10011 => { 0x3ffc000000000000 }, /* 1.75 */\n 0b10100 => { 0x4000000000000000 }, /* 2.0 */\n 0b10101 => { 0x4004000000000000 }, /* 2.5 */\n 0b10110 => { 0x4008000000000000 }, /* 3 */\n 0b10111 => { 0x4010000000000000 }, /* 4 */\n 0b11000 => { 0x4020000000000000 }, /* 8 */\n 0b11001 => { 0x4030000000000000 }, /* 16 */\n 0b11010 => { 0x4060000000000000 }, /* 2^7 */\n 0b11011 => { 0x4070000000000000 }, /* 2^8 */\n 0b11100 => { 0x40e0000000000000 }, /* 2^15 */\n 0b11101 => { 0x40f0000000000000 }, /* 2^16 */\n 0b11110 => { 0x7ff0000000000000 }, /* +inf */\n 0b11111 => { canonical_NaN_D() },\n };\n F_D(rd) = bits;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fli.h", "name": "TBD", "operands": [ { "name": "constantidx", "type": "bits(5)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,constantidx", "format": "TBD", "fields": [ { "field": "0b1111010", "size": 7 }, { "field": "0b00001", "size": 5 }, { "field": "rs1", "size": 3 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let bits : bits(16) = match constantidx {\n 0b00000 => { 0xbc00 }, /* -1.0 */\n 0b00001 => { 0x0400 }, /* minimum positive normal */\n 0b00010 => { 0x0100 }, /* 1.0 * 2^-16 */\n 0b00011 => { 0x0200 }, /* 1.0 * 2^-15 */\n 0b00100 => { 0x1c00 }, /* 1.0 * 2^-8 */\n 0b00101 => { 0x2000 }, /* 1.0 * 2^-7 */\n 0b00110 => { 0x2c00 }, /* 1.0 * 2^-4 */\n 0b00111 => { 0x3000 }, /* 1.0 * 2^-3 */\n 0b01000 => { 0x3400 }, /* 0.25 */\n 0b01001 => { 0x3500 }, /* 0.3125 */\n 0b01010 => { 0x3600 }, /* 0.375 */\n 0b01011 => { 0x3700 }, /* 0.4375 */\n 0b01100 => { 0x3800 }, /* 0.5 */\n 0b01101 => { 0x3900 }, /* 0.625 */\n 0b01110 => { 0x3a00 }, /* 0.75 */\n 0b01111 => { 0x3b00 }, /* 0.875 */\n 0b10000 => { 0x3c00 }, /* 1.0 */\n 0b10001 => { 0x3d00 }, /* 1.25 */\n 0b10010 => { 0x3e00 }, /* 1.5 */\n 0b10011 => { 0x3f00 }, /* 1.75 */\n 0b10100 => { 0x4000 }, /* 2.0 */\n 0b10101 => { 0x4100 }, /* 2.5 */\n 0b10110 => { 0x4200 }, /* 3 */\n 0b10111 => { 0x4400 }, /* 4 */\n 0b11000 => { 0x4800 }, /* 8 */\n 0b11001 => { 0x4c00 }, /* 16 */\n 0b11010 => { 0x5800 }, /* 2^7 */\n 0b11011 => { 0x5c00 }, /* 2^8 */\n 0b11100 => { 0x7800 }, /* 2^15 */\n 0b11101 => { 0x7c00 }, /* 2^16 */\n 0b11110 => { 0x7c00 }, /* +inf */\n 0b11111 => { canonical_NaN_H() },\n };\n F_H(rd) = bits;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fli.s", "name": "TBD", "operands": [ { "name": "constantidx", "type": "bits(5)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,constantidx", "format": "TBD", "fields": [ { "field": "0b1111000", "size": 7 }, { "field": "0b00001", "size": 5 }, { "field": "rs1", "size": 3 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let bits : bits(32) = match constantidx {\n 0b00000 => { 0xbf800000 }, /* -1.0 */\n 0b00001 => { 0x00800000 }, /* minimum positive normal */\n 0b00010 => { 0x37800000 }, /* 1.0 * 2^-16 */\n 0b00011 => { 0x38000000 }, /* 1.0 * 2^-15 */\n 0b00100 => { 0x3b800000 }, /* 1.0 * 2^-8 */\n 0b00101 => { 0x3c000000 }, /* 1.0 * 2^-7 */\n 0b00110 => { 0x3d800000 }, /* 1.0 * 2^-4 */\n 0b00111 => { 0x3e000000 }, /* 1.0 * 2^-3 */\n 0b01000 => { 0x3e800000 }, /* 0.25 */\n 0b01001 => { 0x3ea00000 }, /* 0.3125 */\n 0b01010 => { 0x3ec00000 }, /* 0.375 */\n 0b01011 => { 0x3ee00000 }, /* 0.4375 */\n 0b01100 => { 0x3f000000 }, /* 0.5 */\n 0b01101 => { 0x3f200000 }, /* 0.625 */\n 0b01110 => { 0x3f400000 }, /* 0.75 */\n 0b01111 => { 0x3f600000 }, /* 0.875 */\n 0b10000 => { 0x3f800000 }, /* 1.0 */\n 0b10001 => { 0x3fa00000 }, /* 1.25 */\n 0b10010 => { 0x3fc00000 }, /* 1.5 */\n 0b10011 => { 0x3fe00000 }, /* 1.75 */\n 0b10100 => { 0x40000000 }, /* 2.0 */\n 0b10101 => { 0x40200000 }, /* 2.5 */\n 0b10110 => { 0x40400000 }, /* 3 */\n 0b10111 => { 0x40800000 }, /* 4 */\n 0b11000 => { 0x41000000 }, /* 8 */\n 0b11001 => { 0x41800000 }, /* 16 */\n 0b11010 => { 0x43000000 }, /* 2^7 */\n 0b11011 => { 0x43800000 }, /* 2^8 */\n 0b11100 => { 0x47000000 }, /* 2^15 */\n 0b11101 => { 0x47800000 }, /* 2^16 */\n 0b11110 => { 0x7f800000 }, /* +inf */\n 0b11111 => { canonical_NaN_S() },\n };\n F_S(rd) = bits;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "flt.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "flt.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "flt.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fltq.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F_D(rs1);\n let rs2_val_D = F_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Lt_quiet (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fltq.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let rs1_val_H = F_H(rs1);\n let rs2_val_H = F_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Lt_quiet (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fltq.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let rs1_val_S = F_S(rs1);\n let rs2_val_S = F_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Lt_quiet (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "flw", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let (aq, rl, res) = (false, false, false);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF =>\n process_fload16(rd, vaddr, mem_read(Read(Data), addr, 2, aq, rl, res)),\n WORD =>\n process_fload32(rd, vaddr, mem_read(Read(Data), addr, 4, aq, rl, res)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fload64(rd, vaddr, mem_read(Read(Data), addr, 8, aq, rl, res)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point load\"),\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmadd.d", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_D" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b01", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n let rs3_val_64b = F_or_X_D(rs3);\n\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) =\n match op {\n FMADD_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, rs3_val_64b),\n FMSUB_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, negate_D (rs3_val_64b)),\n FNMSUB_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, rs3_val_64b),\n FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmadd.h", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_H" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n let rs3_val_16b = F_or_X_H(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) =\n match op {\n FMADD_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, rs3_val_16b),\n FMSUB_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, negate_H (rs3_val_16b)),\n FNMSUB_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, rs3_val_16b),\n FNMADD_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, negate_H (rs3_val_16b))\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmadd.s", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_S" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b00", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n let rs3_val_32b = F_or_X_S(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) =\n match op {\n FMADD_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, rs3_val_32b),\n FMSUB_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, negate_S (rs3_val_32b)),\n FNMSUB_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, rs3_val_32b),\n FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmax.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmax.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmax.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmaxm.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F(rs1);\n let rs2_val_D = F(rs2);\n\n let is_quiet = true;\n let (rs2_lt_rs1, fflags) = fle_D (rs2_val_D, rs1_val_D, is_quiet);\n\n let rd_val_D = if (f_is_NaN_D(rs1_val_D) | f_is_NaN_D(rs2_val_D)) then canonical_NaN_D()\n else if (f_is_neg_zero_D(rs1_val_D) & f_is_pos_zero_D(rs2_val_D)) then rs2_val_D\n else if (f_is_neg_zero_D(rs2_val_D) & f_is_pos_zero_D(rs1_val_D)) then rs1_val_D\n else if rs2_lt_rs1 then rs1_val_D\n else rs2_val_D;\n\n accrue_fflags(fflags);\n F(rd) = rd_val_D;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmaxm.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010110", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let rs1_val_H = F_H(rs1);\n let rs2_val_H = F_H(rs2);\n\n let is_quiet = true;\n let (rs2_lt_rs1, fflags) = fle_H (rs2_val_H, rs1_val_H, is_quiet);\n\n let rd_val_H = if (f_is_NaN_H(rs1_val_H) | f_is_NaN_H(rs2_val_H)) then canonical_NaN_H()\n else if (f_is_neg_zero_H(rs1_val_H) & f_is_pos_zero_H(rs2_val_H)) then rs2_val_H\n else if (f_is_neg_zero_H(rs2_val_H) & f_is_pos_zero_H(rs1_val_H)) then rs1_val_H\n else if rs2_lt_rs1 then rs1_val_H\n else /* (not rs2_lt_rs1) */ rs2_val_H;\n\n accrue_fflags(fflags);\n F_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmaxm.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let rs1_val_S = F_S(rs1);\n let rs2_val_S = F_S(rs2);\n\n let is_quiet = true;\n let (rs2_lt_rs1, fflags) = fle_S (rs2_val_S, rs1_val_S, is_quiet);\n\n let rd_val_S = if (f_is_NaN_S(rs1_val_S) | f_is_NaN_S(rs2_val_S)) then canonical_NaN_S()\n else if (f_is_neg_zero_S(rs1_val_S) & f_is_pos_zero_S(rs2_val_S)) then rs2_val_S\n else if (f_is_neg_zero_S(rs2_val_S) & f_is_pos_zero_S(rs1_val_S)) then rs1_val_S\n else if rs2_lt_rs1 then rs1_val_S\n else /* (not rs2_lt_rs1) */ rs2_val_S;\n\n accrue_fflags(fflags);\n F_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmin.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmin.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmin.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fminm.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F(rs1);\n let rs2_val_D = F(rs2);\n\n let is_quiet = true;\n let (rs1_lt_rs2, fflags) = fle_D (rs1_val_D, rs2_val_D, is_quiet);\n\n let rd_val_D = if (f_is_NaN_D(rs1_val_D) | f_is_NaN_D(rs2_val_D)) then canonical_NaN_D()\n else if (f_is_neg_zero_D(rs1_val_D) & f_is_pos_zero_D(rs2_val_D)) then rs1_val_D\n else if (f_is_neg_zero_D(rs2_val_D) & f_is_pos_zero_D(rs1_val_D)) then rs2_val_D\n else if rs1_lt_rs2 then rs1_val_D\n else rs2_val_D;\n\n accrue_fflags(fflags);\n F(rd) = rd_val_D;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fminm.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010110", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let rs1_val_H = F_H(rs1);\n let rs2_val_H = F_H(rs2);\n\n let is_quiet = true;\n let (rs1_lt_rs2, fflags) = fle_H (rs1_val_H, rs2_val_H, is_quiet);\n\n let rd_val_H = if (f_is_NaN_H(rs1_val_H) | f_is_NaN_H(rs2_val_H)) then canonical_NaN_H()\n else if (f_is_neg_zero_H(rs1_val_H) & f_is_pos_zero_H(rs2_val_H)) then rs1_val_H\n else if (f_is_neg_zero_H(rs2_val_H) & f_is_pos_zero_H(rs1_val_H)) then rs2_val_H\n else if rs1_lt_rs2 then rs1_val_H\n else /* (not rs1_lt_rs2) */ rs2_val_H;\n\n accrue_fflags(fflags);\n F_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fminm.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let rs1_val_S = F_S(rs1);\n let rs2_val_S = F_S(rs2);\n\n let is_quiet = true;\n let (rs1_lt_rs2, fflags) = fle_S (rs1_val_S, rs2_val_S, is_quiet);\n\n let rd_val_S = if (f_is_NaN_S(rs1_val_S) | f_is_NaN_S(rs2_val_S)) then canonical_NaN_S()\n else if (f_is_neg_zero_S(rs1_val_S) & f_is_pos_zero_S(rs2_val_S)) then rs1_val_S\n else if (f_is_neg_zero_S(rs2_val_S) & f_is_pos_zero_S(rs1_val_S)) then rs2_val_S\n else if rs1_lt_rs2 then rs1_val_S\n else /* (not rs1_lt_rs2) */ rs2_val_S;\n\n accrue_fflags(fflags);\n F_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmsub.d", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_D" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b01", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n let rs3_val_64b = F_or_X_D(rs3);\n\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) =\n match op {\n FMADD_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, rs3_val_64b),\n FMSUB_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, negate_D (rs3_val_64b)),\n FNMSUB_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, rs3_val_64b),\n FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmsub.h", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_H" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n let rs3_val_16b = F_or_X_H(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) =\n match op {\n FMADD_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, rs3_val_16b),\n FMSUB_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, negate_H (rs3_val_16b)),\n FNMSUB_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, rs3_val_16b),\n FNMADD_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, negate_H (rs3_val_16b))\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmsub.s", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_S" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b00", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n let rs3_val_32b = F_or_X_S(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) =\n match op {\n FMADD_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, rs3_val_32b),\n FMSUB_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, negate_S (rs3_val_32b)),\n FNMSUB_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, rs3_val_32b),\n FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmul.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_D" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) = match op {\n FADD_D => riscv_f64Add (rm_3b, rs1_val_64b, rs2_val_64b),\n FSUB_D => riscv_f64Sub (rm_3b, rs1_val_64b, rs2_val_64b),\n FMUL_D => riscv_f64Mul (rm_3b, rs1_val_64b, rs2_val_64b),\n FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmul.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_H" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001110", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) = match op {\n FADD_H => riscv_f16Add (rm_3b, rs1_val_16b, rs2_val_16b),\n FSUB_H => riscv_f16Sub (rm_3b, rs1_val_16b, rs2_val_16b),\n FMUL_H => riscv_f16Mul (rm_3b, rs1_val_16b, rs2_val_16b),\n FDIV_H => riscv_f16Div (rm_3b, rs1_val_16b, rs2_val_16b)\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmul.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_S" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) = match op {\n FADD_S => riscv_f32Add (rm_3b, rs1_val_32b, rs2_val_32b),\n FSUB_S => riscv_f32Sub (rm_3b, rs1_val_32b, rs2_val_32b),\n FMUL_S => riscv_f32Mul (rm_3b, rs1_val_32b, rs2_val_32b),\n FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fmv.d.x", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_D_X", "type": "f_un_op_D" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111001", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D" ], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_X = X(rs1);\n let rd_val_D = rs1_val_X [63..0];\n F(rd) = rd_val_D;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmv.h.x", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_H_X", "type": "f_un_op_H" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111010", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh" ], "function": "{\n let rs1_val_X = X(rs1);\n let rd_val_H = rs1_val_X [15..0];\n F(rd) = nan_box (rd_val_H);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmv.w.x", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_W_X", "type": "f_un_op_S" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111000", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "F" ], "function": "{\n let rs1_val_X = X(rs1);\n let rd_val_S = rs1_val_X [31..0];\n F(rd) = nan_box (rd_val_S);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmv.x.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_D_X", "type": "f_un_op_D" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111001", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D" ], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_X = X(rs1);\n let rd_val_D = rs1_val_X [63..0];\n F(rd) = rd_val_D;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmv.x.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_H_X", "type": "f_un_op_H" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111010", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh" ], "function": "{\n let rs1_val_X = X(rs1);\n let rd_val_H = rs1_val_X [15..0];\n F(rd) = nan_box (rd_val_H);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmv.x.w", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FMV_W_X", "type": "f_un_op_S" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1111000", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "F" ], "function": "{\n let rs1_val_X = X(rs1);\n let rd_val_S = rs1_val_X [31..0];\n F(rd) = nan_box (rd_val_S);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmvh.x.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b1110001", "size": 7 }, { "field": "0b00001", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F_D(rs1)[63..32];\n let rd_val_X : xlenbits = sign_extend(rs1_val_D);\n X(rd) = rd_val_X;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fmvp.d.x", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1011001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_X = X(rs1)[31..0];\n let rs2_val_X = X(rs2)[31..0];\n\n /* Concatenate the two values using '@' operator */\n /* e.g. */\n /* rs1 = 0x01234567 */\n /* rs2 = 0x89abcdef */\n /* rd = rs1 @ rs2 => 0x89abcdef01234567 */\n let rd_val_D = rs2_val_X @ rs1_val_X;\n\n F_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fnmadd.d", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_D" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b01", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n let rs3_val_64b = F_or_X_D(rs3);\n\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) =\n match op {\n FMADD_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, rs3_val_64b),\n FMSUB_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, negate_D (rs3_val_64b)),\n FNMSUB_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, rs3_val_64b),\n FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fnmadd.h", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_H" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n let rs3_val_16b = F_or_X_H(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) =\n match op {\n FMADD_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, rs3_val_16b),\n FMSUB_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, negate_H (rs3_val_16b)),\n FNMSUB_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, rs3_val_16b),\n FNMADD_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, negate_H (rs3_val_16b))\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fnmadd.s", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_S" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b00", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n let rs3_val_32b = F_or_X_S(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) =\n match op {\n FMADD_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, rs3_val_32b),\n FMSUB_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, negate_S (rs3_val_32b)),\n FNMSUB_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, rs3_val_32b),\n FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fnmsub.d", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_D" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b01", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n let rs3_val_64b = F_or_X_D(rs3);\n\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) =\n match op {\n FMADD_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, rs3_val_64b),\n FMSUB_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, negate_D (rs3_val_64b)),\n FNMSUB_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, rs3_val_64b),\n FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fnmsub.h", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_H" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b10", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n let rs3_val_16b = F_or_X_H(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) =\n match op {\n FMADD_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, rs3_val_16b),\n FMSUB_H => riscv_f16MulAdd (rm_3b, rs1_val_16b, rs2_val_16b, negate_H (rs3_val_16b)),\n FNMSUB_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, rs3_val_16b),\n FNMADD_H => riscv_f16MulAdd (rm_3b, negate_H (rs1_val_16b), rs2_val_16b, negate_H (rs3_val_16b))\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fnmsub.s", "name": "TBD", "operands": [ { "name": "rs3", "type": "regidx" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_madd_op_S" } ], "syntax": "rd,rs1,rs2,rs3,rm", "format": "TBD", "fields": [ { "field": "rs3", "size": 5 }, { "field": "0b00", "size": 2 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1001111", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n let rs3_val_32b = F_or_X_S(rs3);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) =\n match op {\n FMADD_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, rs3_val_32b),\n FMSUB_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, negate_S (rs3_val_32b)),\n FNMSUB_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, rs3_val_32b),\n FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fround.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b0100001", "size": 7 }, { "field": "0b00100", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F(rs1);\n\n match (select_instr_or_fcsr_rm(rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_f64roundToInt(rm_3b, rs1_val_D, false);\n\n accrue_fflags(fflags);\n F(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fround.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b0100010", "size": 7 }, { "field": "0b00100", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let rs1_val_H = F_H(rs1);\n\n match (select_instr_or_fcsr_rm(rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_f16roundToInt(rm_3b, rs1_val_H, false);\n\n accrue_fflags(fflags);\n F_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fround.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "0b00100", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let rs1_val_S = F_S(rs1);\n\n match (select_instr_or_fcsr_rm(rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_f32roundToInt(rm_3b, rs1_val_S, false);\n\n accrue_fflags(fflags);\n F_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "froundnx.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b0100001", "size": 7 }, { "field": "0b00101", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "D", "Zfa" ], "function": "{\n let rs1_val_D = F_D(rs1);\n\n match (select_instr_or_fcsr_rm(rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_f64roundToInt(rm_3b, rs1_val_D, true);\n\n accrue_fflags(fflags);\n F_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "froundnx.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b0100010", "size": 7 }, { "field": "0b00101", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfh", "Zfa" ], "function": "{\n let rs1_val_H = F_H(rs1);\n\n match (select_instr_or_fcsr_rm(rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_f16roundToInt(rm_3b, rs1_val_H, true);\n\n accrue_fflags(fflags);\n F_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "froundnx.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "0b00101", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [ "Zfa" ], "function": "{\n let rs1_val_S = F_S(rs1);\n\n match (select_instr_or_fcsr_rm(rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_f32roundToInt(rm_3b, rs1_val_S, true);\n\n accrue_fflags(fflags);\n F_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsb", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n let (aq, rl, con) = (false, false, false);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => MemValue () /* bogus placeholder for illegal size */,\n HALF => mem_write_ea(addr, 2, aq, rl, false),\n WORD => mem_write_ea(addr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(addr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = F(rs2);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF => process_fstore (vaddr, mem_write_value(addr, 2, rs2_val[15..0], aq, rl, con)),\n WORD => process_fstore (vaddr, mem_write_value(addr, 4, rs2_val[31..0], aq, rl, con)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fstore (vaddr, mem_write_value(addr, 8, rs2_val, aq, rl, con)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point store\"),\n };\n }\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsd", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n let (aq, rl, con) = (false, false, false);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => MemValue () /* bogus placeholder for illegal size */,\n HALF => mem_write_ea(addr, 2, aq, rl, false),\n WORD => mem_write_ea(addr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(addr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = F(rs2);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF => process_fstore (vaddr, mem_write_value(addr, 2, rs2_val[15..0], aq, rl, con)),\n WORD => process_fstore (vaddr, mem_write_value(addr, 4, rs2_val[31..0], aq, rl, con)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fstore (vaddr, mem_write_value(addr, 8, rs2_val, aq, rl, con)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point store\"),\n };\n }\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsgnj.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnj.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnj.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnjn.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnjn.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnjn.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnjx.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_D", "type": "f_bin_op_D" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_D = F_or_X_D(rs1);\n let rs2_val_D = F_or_X_D(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f64Le (rs1_val_D, rs2_val_D);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnjx.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_H", "type": "f_bin_op_H" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010010", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_H = F_or_X_H(rs1);\n let rs2_val_H = F_or_X_H(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f16Le (rs1_val_H, rs2_val_H);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsgnjx.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "FLE_S", "type": "f_bin_op_S" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b1010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_S = F_or_X_S(rs1);\n let rs2_val_S = F_or_X_S(rs2);\n\n let (fflags, rd_val) : (bits_fflags, bool) =\n riscv_f32Le (rs1_val_S, rs2_val_S);\n\n accrue_fflags(fflags);\n X(rd) = zero_extend(bool_to_bits(rd_val));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "fsh", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n let (aq, rl, con) = (false, false, false);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => MemValue () /* bogus placeholder for illegal size */,\n HALF => mem_write_ea(addr, 2, aq, rl, false),\n WORD => mem_write_ea(addr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(addr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = F(rs2);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF => process_fstore (vaddr, mem_write_value(addr, 2, rs2_val[15..0], aq, rl, con)),\n WORD => process_fstore (vaddr, mem_write_value(addr, 4, rs2_val[31..0], aq, rl, con)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fstore (vaddr, mem_write_value(addr, 8, rs2_val, aq, rl, con)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point store\"),\n };\n }\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsqrt.d", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_D_LU", "type": "f_un_rm_op_D" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101001", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_D;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsqrt.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_H_LU", "type": "f_un_rm_op_H" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101010", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_H;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsqrt.s", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "FCVT_S_LU", "type": "f_un_rm_op_S" } ], "syntax": "rd,rs1,rm", "format": "TBD", "fields": [ { "field": "0b1101000", "size": 7 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n assert(sizeof(xlen) >= 64);\n let rs1_val_LU = X(rs1)[63..0];\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);\n\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_S;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsub.d", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_D" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001101", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_64b = F_or_X_D(rs1);\n let rs2_val_64b = F_or_X_D(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_64b) : (bits(5), bits(64)) = match op {\n FADD_D => riscv_f64Add (rm_3b, rs1_val_64b, rs2_val_64b),\n FSUB_D => riscv_f64Sub (rm_3b, rs1_val_64b, rs2_val_64b),\n FMUL_D => riscv_f64Mul (rm_3b, rs1_val_64b, rs2_val_64b),\n FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)\n };\n accrue_fflags(fflags);\n F_or_X_D(rd) = rd_val_64b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsub.h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_H" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001110", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_16b = F_or_X_H(rs1);\n let rs2_val_16b = F_or_X_H(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_16b) : (bits(5), bits(16)) = match op {\n FADD_H => riscv_f16Add (rm_3b, rs1_val_16b, rs2_val_16b),\n FSUB_H => riscv_f16Sub (rm_3b, rs1_val_16b, rs2_val_16b),\n FMUL_H => riscv_f16Mul (rm_3b, rs1_val_16b, rs2_val_16b),\n FDIV_H => riscv_f16Div (rm_3b, rs1_val_16b, rs2_val_16b)\n };\n accrue_fflags(fflags);\n F_or_X_H(rd) = rd_val_16b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsub.s", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rm", "type": "rounding_mode" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "f_bin_rm_op_S" } ], "syntax": "rd,rs1,rs2,rm", "format": "TBD", "fields": [ { "field": "0b0001100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_rounding_mode(rm)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val_32b = F_or_X_S(rs1);\n let rs2_val_32b = F_or_X_S(rs2);\n match (select_instr_or_fcsr_rm (rm)) {\n None() => { handle_illegal(); RETIRE_FAIL },\n Some(rm') => {\n let rm_3b = encdec_rounding_mode(rm');\n let (fflags, rd_val_32b) : (bits(5), bits(32)) = match op {\n FADD_S => riscv_f32Add (rm_3b, rs1_val_32b, rs2_val_32b),\n FSUB_S => riscv_f32Sub (rm_3b, rs1_val_32b, rs2_val_32b),\n FMUL_S => riscv_f32Mul (rm_3b, rs1_val_32b, rs2_val_32b),\n FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)\n };\n accrue_fflags(fflags);\n F_or_X_S(rd) = rd_val_32b;\n RETIRE_SUCCESS\n }\n }\n}", "description": "TBD" }, { "mnemonic": "fsw", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "imm5", "size": 1 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "D" ], "function": "{\n let offset : xlenbits = sign_extend(imm);\n let (aq, rl, con) = (false, false, false);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => MemValue () /* bogus placeholder for illegal size */,\n HALF => mem_write_ea(addr, 2, aq, rl, false),\n WORD => mem_write_ea(addr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(addr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = F(rs2);\n match (width) {\n BYTE => { handle_illegal(); RETIRE_FAIL },\n HALF => process_fstore (vaddr, mem_write_value(addr, 2, rs2_val[15..0], aq, rl, con)),\n WORD => process_fstore (vaddr, mem_write_value(addr, 4, rs2_val[31..0], aq, rl, con)),\n DOUBLE if sizeof(flen) >= 64 =>\n process_fstore (vaddr, mem_write_value(addr, 8, rs2_val, aq, rl, con)),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"floating point store\"),\n };\n }\n }\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "illegal", "name": "TBD", "operands": [ { "name": "s", "type": "word" } ], "syntax": "s", "format": "TBD", "fields": [ { "field": "s", "size": 32 } ], "extensions": [], "function": "{ handle_illegal(); RETIRE_FAIL }", "description": "TBD" }, { "mnemonic": "jal", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(21)" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,imm", "format": "TBD", "fields": [ { "field": "imm_19", "size": 1 }, { "field": "imm_18_13", "size": 6 }, { "field": "imm_12_9", "size": 4 }, { "field": "imm_8", "size": 1 }, { "field": "imm_7_0", "size": 8 }, { "field": "rd", "size": 5 }, { "field": "0b1101111", "size": 7 } ], "extensions": [], "function": "{\n let t : xlenbits = PC + sign_extend(imm);\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_pc(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(target) => {\n /* Perform standard alignment check */\n if bit_to_bool(target[1]) & not(extension(\"C\"))\n then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL\n } else {\n X(rd) = get_next_pc();\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n}", "description": "TBD" }, { "mnemonic": "jalr", "name": "Jump And Link Register", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,imm", "format": "I", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1100111", "size": 7 } ], "extensions": [], "function": "{\n/* For the sequential model, the memory-model definition doesn't work directly\n * if rs1 = rd. We would effectively have to keep a regfile for reads and another for\n * writes, and swap on instruction completion. This could perhaps be optimized in\n * some manner, but for now, we just keep a reordered definition to improve simulator\n * performance.\n */\n let t : xlenbits = X(rs1) + sign_extend(imm);\n /* Extensions get the first checks on the prospective target address. */\n match ext_control_check_addr(t) {\n Ext_ControlAddr_Error(e) => {\n ext_handle_control_check_error(e);\n RETIRE_FAIL\n },\n Ext_ControlAddr_OK(addr) => {\n let target = [addr with 0 = bitzero]; /* clear addr[0] */\n if bit_to_bool(target[1]) & not(extension(\"C\")) then {\n handle_mem_exception(target, E_Fetch_Addr_Align());\n RETIRE_FAIL\n } else {\n X(rd) = get_next_pc();\n set_next_pc(target);\n RETIRE_SUCCESS\n }\n }\n }\n}", "description": "\nThe target address is obtained by adding the sign-extended 12-bit\nI-immediate to the register rs1, then setting the\nleast-significant bit of the result to zero. The address of the\ninstruction following the jump (pc+4) is written to register rd.\nRegister x0 can be used as the destination if the result is not\nrequired.\n " }, { "mnemonic": "lb", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lb.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lb.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lb.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lbu", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lbu.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lbu.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lbu.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ld", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ld.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ld.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ld.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ldu", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ldu.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ldu.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "ldu.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lh", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lh.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lh.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lh.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lhu", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lhu.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lhu.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lhu.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lr.b", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.b.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.b.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.b.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.d", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.d.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.d.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.d.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.h", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.h.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.h.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.h.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.w", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.w.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.w.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lr.w.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00010", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if extension(\"A\") then {\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n /* \"LR faults like a normal load, even though it's in the AMO major opcode space.\"\n * - Andrew Waterman, isa-dev, 10 Jul 2018.\n */\n if not(aligned)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) =>\n match (width, sizeof(xlen)) {\n (BYTE, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),\n (HALF, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),\n (WORD, _) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),\n (DOUBLE, 64) => process_loadres(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),\n _ => internal_error(__FILE__, __LINE__, \"Unexpected AMO width\")\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "lui", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(20)" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "uop" } ], "syntax": "rd,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 20 }, { "field": "rd", "size": 5 }, { "field": "encdec_uop(op)", "size": 7 } ], "extensions": [], "function": "{\n let off : xlenbits = sign_extend(imm @ 0x000);\n let ret : xlenbits = match op {\n RISCV_LUI => off,\n RISCV_AUIPC => get_arch_pc() + off\n };\n X(rd) = ret;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "lw", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lw.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lw.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lw.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lwu", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lwu.aq", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lwu.aq.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "lwu.rl", "name": "Load", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "is_unsigned", "type": "bool" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rd,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "bool_bits(is_unsigned)", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0000011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Read(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Read(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) =>\n match (width) {\n BYTE =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),\n HALF =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),\n WORD =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),\n DOUBLE if sizeof(xlen) >= 64 =>\n process_load(rd, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"load\")\n }\n }\n }\n}", "description": "\nThe LOAD instruction format is used for loading data from memory into a\nregister. The specific operation is determined by the word width (size),\nwhether the load is signed or unsigned (is_unsigned), and memory ordering\nsemantics (acquire, release). The result is written to the destination\nregister (rd), and the memory address is computed by adding the immediate\noffset (imm) to the value in register rs1.\n " }, { "mnemonic": "max", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "maxu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "min", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "minu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "mret", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b0011000", "size": 7 }, { "field": "0b00010", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n if cur_privilege != Machine\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_xret_priv (Machine))\n then { ext_fail_xret_priv(); RETIRE_FAIL }\n else {\n set_next_pc(exception_handler(cur_privilege, CTL_MRET(), PC));\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "mul", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "high", "type": "bool" }, { "name": "signed1", "type": "bool" }, { "name": "signed2", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_mul_op(high,signed1,signed2)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") | haveZmmul() then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if signed1 then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if signed2 then signed(rs2_val) else unsigned(rs2_val);\n let result_wide = to_bits(2 * sizeof(xlen), rs1_int * rs2_int);\n let result = if high\n then result_wide[(2 * sizeof(xlen) - 1) .. sizeof(xlen)]\n else result_wide[(sizeof(xlen) - 1) .. 0];\n X(rd) = result;\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "mulh", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "high", "type": "bool" }, { "name": "signed1", "type": "bool" }, { "name": "signed2", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_mul_op(high,signed1,signed2)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") | haveZmmul() then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if signed1 then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if signed2 then signed(rs2_val) else unsigned(rs2_val);\n let result_wide = to_bits(2 * sizeof(xlen), rs1_int * rs2_int);\n let result = if high\n then result_wide[(2 * sizeof(xlen) - 1) .. sizeof(xlen)]\n else result_wide[(sizeof(xlen) - 1) .. 0];\n X(rd) = result;\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "mulhsu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "high", "type": "bool" }, { "name": "signed1", "type": "bool" }, { "name": "signed2", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_mul_op(high,signed1,signed2)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") | haveZmmul() then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if signed1 then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if signed2 then signed(rs2_val) else unsigned(rs2_val);\n let result_wide = to_bits(2 * sizeof(xlen), rs1_int * rs2_int);\n let result = if high\n then result_wide[(2 * sizeof(xlen) - 1) .. sizeof(xlen)]\n else result_wide[(sizeof(xlen) - 1) .. 0];\n X(rd) = result;\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "mulhu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "high", "type": "bool" }, { "name": "signed1", "type": "bool" }, { "name": "signed2", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_mul_op(high,signed1,signed2)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") | haveZmmul() then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if signed1 then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if signed2 then signed(rs2_val) else unsigned(rs2_val);\n let result_wide = to_bits(2 * sizeof(xlen), rs1_int * rs2_int);\n let result = if high\n then result_wide[(2 * sizeof(xlen) - 1) .. sizeof(xlen)]\n else result_wide[(sizeof(xlen) - 1) .. 0];\n X(rd) = result;\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "mulw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") | haveZmmul() then {\n let rs1_val = X(rs1)[31..0];\n let rs2_val = X(rs2)[31..0];\n let rs1_int : int = signed(rs1_val);\n let rs2_int : int = signed(rs2_val);\n /* to_bits requires expansion to 64 bits followed by truncation */\n let result32 = to_bits(64, rs1_int * rs2_int)[31..0];\n let result : xlenbits = sign_extend(result32);\n X(rd) = result;\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "or", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "orc.b", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b001010000111", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen) - 8) by 8)\n result[(i + 7) .. i] = if rs1_val[(i + 7) .. i] == zeros()\n then 0x00\n else 0xFF;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "ori", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "iop" } ], "syntax": "rd,rs1,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "encdec_iop(op)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let immext : xlenbits = sign_extend(imm);\n let result : xlenbits = match op {\n RISCV_ADDI => rs1_val + immext,\n RISCV_SLTI => zero_extend(bool_to_bits(rs1_val <_s immext)),\n RISCV_SLTIU => zero_extend(bool_to_bits(rs1_val <_u immext)),\n RISCV_ANDI => rs1_val & immext,\n RISCV_ORI => rs1_val | immext,\n RISCV_XORI => rs1_val ^ immext\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe ITYPE instruction operates on an immediate value, adding, comparing, or\nperforming bitwise operations with the contents of register rs1.\nThe immediate value, rs1, and the operation code (iop) determine the operation.\nThe result is stored in register rd.\nThe supported immediate operations (iop) include:\n - \"addi\" : Add immediate\n - \"slti\" : Set less than immediate (signed)\n - \"sltiu\" : Set less than immediate (unsigned)\n - \"andi\" : AND immediate\n - \"ori\" : OR immediate\n - \"xori\" : XOR immediate\n *\nNote: The immediate value is sign-extended before performing the operation.\n " }, { "mnemonic": "orn", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "pack", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbkb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_PACK => rs2_val[(sizeof(xlen_bytes)*4 - 1)..0] @ rs1_val[(sizeof(xlen_bytes)*4 - 1)..0],\n RISCV_PACKH => zero_extend(rs2_val[7..0] @ rs1_val[7..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "packh", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbkb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_PACK => rs2_val[(sizeof(xlen_bytes)*4 - 1)..0] @ rs1_val[(sizeof(xlen_bytes)*4 - 1)..0],\n RISCV_PACKH => zero_extend(rs2_val[7..0] @ rs1_val[7..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "packw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zbkb" ], "function": "{\n assert(sizeof(xlen) == 64);\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : bits(32) = rs2_val[15..0] @ rs1_val[15..0];\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "rem", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b11", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let r : int = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n X(rd) = to_bits(sizeof(xlen), r);\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "remu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b11", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let r : int = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n X(rd) = to_bits(sizeof(xlen), r);\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "remuw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b11", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1)[31..0];\n let rs2_val = X(rs2)[31..0];\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let r : int = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n X(rd) = sign_extend(to_bits(32, r));\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "remw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "s", "type": "bool" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0000001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b11", "size": 2 }, { "field": "bool_not_bits(s)", "size": 1 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "M" ], "function": "{\n if extension(\"M\") then {\n let rs1_val = X(rs1)[31..0];\n let rs2_val = X(rs2)[31..0];\n let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);\n let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);\n let r : int = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n X(rd) = sign_extend(to_bits(32, r));\n RETIRE_SUCCESS\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n}", "description": "TBD" }, { "mnemonic": "rev8", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b011010111000", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen) - 8) by 8)\n result[(i + 7) .. i] = rs1_val[(sizeof(xlen) - i - 1) .. (sizeof(xlen) - i - 8)];\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "rol", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "rolw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "bropw_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let shamt = (X(rs2))[4..0];\n let result : bits(32) = match op {\n RISCV_ROLW => rs1_val <<< shamt,\n RISCV_RORW => rs1_val >>> shamt\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "ror", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "rori", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b011000", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let result : xlenbits = if sizeof(xlen) == 32\n then rs1_val >>> shamt[4..0]\n else rs1_val >>> shamt;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "roriw", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(5)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "shamt", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let result : xlenbits = sign_extend(rs1_val >>> shamt);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "rorw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "bropw_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let shamt = (X(rs2))[4..0];\n let result : bits(32) = match op {\n RISCV_ROLW => rs1_val <<< shamt,\n RISCV_RORW => rs1_val >>> shamt\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sb", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sb.aq", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sb.aq.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sb.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sc.b", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.b.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.b.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.b.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.d", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.d.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.d.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.d.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.h", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.h.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.h.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.h.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.w", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.w.aq", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.w.aq.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sc.w.rl", "name": "TBD", "operands": [ { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b00011", "size": 5 }, { "field": "bool_bits(aq)", "size": 1 }, { "field": "bool_bits(rl)", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "rd", "size": 5 }, { "field": "0b0101111", "size": 7 } ], "extensions": [ "A" ], "function": "{\n if speculate_conditional () == false then {\n /* should only happen in rmem\n * rmem: allow SC to fail very early\n */\n X(rd) = zero_extend(0b1); RETIRE_SUCCESS\n } else {\n if extension(\"A\") then {\n /* normal non-rmem case\n * rmem: SC is allowed to succeed (but might fail later)\n */\n /* Get the address, X(rs1) (no offset).\n * Extensions might perform additional checks on address validity.\n */\n match ext_data_get_addr(rs1, zeros(), Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) => {\n let aligned : bool =\n /* BYTE and HALF would only occur due to invalid decodes, but it doesn't hurt\n * to treat them as valid here; otherwise we'd need to throw an internal_error.\n */\n match width {\n BYTE => true,\n HALF => vaddr[0..0] == 0b0,\n WORD => vaddr[1..0] == 0b00,\n DOUBLE => vaddr[2..0] == 0b000\n };\n if not(aligned)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else {\n if match_reservation(vaddr) == false then {\n /* cannot happen in rmem */\n X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS\n } else {\n match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:\n * both result in a SAMO exception */\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(addr, _) => {\n let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),\n (HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),\n (WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {\n (BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),\n (HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),\n (WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),\n (DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),\n _ => internal_error(__FILE__, __LINE__, \"STORECON expected word or double\")\n };\n match (res) {\n MemValue(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },\n MemValue(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n handle_illegal();\n RETIRE_FAIL\n }\n }\n}", "description": "TBD" }, { "mnemonic": "sd", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sd.aq", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sd.aq.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sd.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sext.b", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "extop_zbb" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b0000100", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n let result : xlenbits = match op {\n RISCV_SEXTB => sign_extend(rs1_val[7..0]),\n RISCV_SEXTH => sign_extend(rs1_val[15..0]),\n RISCV_ZEXTH => zero_extend(rs1_val[15..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sext.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "extop_zbb" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b0000100", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n let result : xlenbits = match op {\n RISCV_SEXTB => sign_extend(rs1_val[7..0]),\n RISCV_SEXTH => sign_extend(rs1_val[15..0]),\n RISCV_ZEXTH => zero_extend(rs1_val[15..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sfence.vma", "name": "Store Fence (Virtual Memory Address)", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rs2", "type": "regidx" } ], "syntax": "rs1,rs2", "format": "R", "fields": [ { "field": "0b0001001", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let addr : option(xlenbits) = if rs1 == 0b00000 then None() else Some(X(rs1));\n let asid : option(xlenbits) = if rs2 == 0b00000 then None() else Some(X(rs2));\n match cur_privilege {\n User => { handle_illegal(); RETIRE_FAIL },\n Supervisor => match (architecture(get_mstatus_SXL(mstatus)), mstatus.TVM()) {\n (Some(_), 0b1) => { handle_illegal(); RETIRE_FAIL },\n (Some(_), 0b0) => { flush_TLB(asid, addr); RETIRE_SUCCESS },\n (_, _) => internal_error(__FILE__, __LINE__, \"unimplemented sfence architecture\")\n },\n Machine => { flush_TLB(asid, addr); RETIRE_SUCCESS }\n }\n}", "description": "\nThe SFENCE.VMA instruction is used to synchronize the store queue and flush\nTLB entries based on virtual memory address and optional ASID values.\nIts behavior depends on the current privilege level:\n- In User mode, it handles the illegal instruction and returns with RETIRE_FAIL.\n- In Supervisor mode, it checks for illegal instructions and performs TLB\n flushing based on the provided virtual memory address and ASID values.\n- In Machine mode, it performs TLB flushing based on the provided virtual\n memory address and ASID values.\n " }, { "mnemonic": "sh", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sh.aq", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sh.aq.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sh.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sh1add", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_SH1ADD => 0b01,\n RISCV_SH2ADD => 0b10,\n RISCV_SH3ADD => 0b11\n };\n let result : xlenbits = (rs1_val << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sh1add.uw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "bropw_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_ADDUW => 0b00,\n RISCV_SH1ADDUW => 0b01,\n RISCV_SH2ADDUW => 0b10,\n RISCV_SH3ADDUW => 0b11\n };\n let result : xlenbits = (zero_extend(rs1_val[31..0]) << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sh2add", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_SH1ADD => 0b01,\n RISCV_SH2ADD => 0b10,\n RISCV_SH3ADD => 0b11\n };\n let result : xlenbits = (rs1_val << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sh2add.uw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "bropw_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_ADDUW => 0b00,\n RISCV_SH1ADDUW => 0b01,\n RISCV_SH2ADDUW => 0b10,\n RISCV_SH3ADDUW => 0b11\n };\n let result : xlenbits = (zero_extend(rs1_val[31..0]) << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sh3add", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_SH1ADD => 0b01,\n RISCV_SH2ADD => 0b10,\n RISCV_SH3ADD => 0b11\n };\n let result : xlenbits = (rs1_val << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sh3add.uw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "bropw_zba" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let shamt : bits(2) = match op {\n RISCV_ADDUW => 0b00,\n RISCV_SH1ADDUW => 0b01,\n RISCV_SH2ADDUW => 0b10,\n RISCV_SH3ADDUW => 0b11\n };\n let result : xlenbits = (zero_extend(rs1_val[31..0]) << shamt) + rs2_val;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha256sig0", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00010", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n let inb : bits(32) = X(rs1)[31..0];\n let result : bits(32) = (inb >>> 7) ^ (inb >>> 18) ^ (inb >> 3);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha256sig1", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n let inb : bits(32) = X(rs1)[31..0];\n let result : bits(32) = (inb >>> 17) ^ (inb >>> 19) ^ (inb >> 10);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha256sum0", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n let inb : bits(32) = X(rs1)[31..0];\n let result : bits(32) = (inb >>> 2) ^ (inb >>> 13) ^ (inb >>> 22);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha256sum1", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00001", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n let inb : bits(32) = X(rs1)[31..0];\n let result : bits(32) = (inb >>> 6) ^ (inb >>> 11) ^ (inb >>> 25);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sig0", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00110", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n assert(sizeof(xlen) == 64);\n let input : bits(64) = X(rs1);\n let result : bits(64) = (input >>> 1) ^ (input >>> 8) ^ (input >> 7);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sig0h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b01110", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n X(rd) = sign_extend((X(rs1) >> 1) ^ (X(rs1) >> 7) ^ (X(rs1) >> 8) ^\n (X(rs2) << 31) ^ (X(rs2) << 24));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sig0l", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b01010", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n X(rd) = sign_extend((X(rs1) >> 1) ^ (X(rs1) >> 7) ^ (X(rs1) >> 8) ^\n (X(rs2) << 31) ^ (X(rs2) << 25) ^ (X(rs2) << 24));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sig1", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00111", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n assert(sizeof(xlen) == 64);\n let input : bits(64) = X(rs1);\n let result : bits(64) = (input >>> 19) ^ (input >>> 61) ^ (input >> 6);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sig1h", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b01111", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n X(rd) = sign_extend((X(rs1) << 3) ^ (X(rs1) >> 6) ^ (X(rs1) >> 19) ^\n (X(rs2) >> 29) ^ (X(rs2) << 13));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sig1l", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b01011", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n X(rd) = sign_extend((X(rs1) << 3) ^ (X(rs1) >> 6) ^ (X(rs1) >> 19) ^\n (X(rs2) >> 29) ^ (X(rs2) << 26) ^ (X(rs2) << 13));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sum0", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00100", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n assert(sizeof(xlen) == 64);\n let input : bits(64) = X(rs1);\n let result : bits(64) = (input >>> 28) ^ (input >>> 34) ^ (input >>> 39);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sum0r", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n X(rd) = sign_extend((X(rs1) << 25) ^ (X(rs1) << 30) ^ (X(rs1) >> 28) ^\n (X(rs2) >> 7) ^ (X(rs2) >> 2) ^ (X(rs2) << 4));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sum1", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b00101", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n assert(sizeof(xlen) == 64);\n let input : bits(64) = X(rs1);\n let result : bits(64) = (input >>> 14) ^ (input >>> 18) ^ (input >>> 41);\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sha512sum1r", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b01", "size": 2 }, { "field": "0b01001", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zknh" ], "function": "{\n X(rd) = sign_extend((X(rs1) << 23) ^ (X(rs1) >> 14) ^ (X(rs1) >> 18) ^\n (X(rs2) >> 9) ^ (X(rs2) << 18) ^ (X(rs2) << 14));\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sll", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "slli", "name": "Shift Immediate", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "sop" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n /* the decoder guard should ensure that shamt[5] = 0 for RV32 */\n let result : xlenbits = match op {\n RISCV_SLLI => if sizeof(xlen) == 32\n then rs1_val << shamt[4..0]\n else rs1_val << shamt,\n RISCV_SRLI => if sizeof(xlen) == 32\n then rs1_val >> shamt[4..0]\n else rs1_val >> shamt,\n RISCV_SRAI => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, shamt[4..0])\n else shift_right_arith64(rs1_val, shamt)\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe SHIFTIOP (Shift Immediate Operation) instruction format is used for\noperations that involve shifting the bits of a register by an immediate\nvalue. The specific operation is determined by the opcode field, and the\nshift amount is specified by the immediate value (shamt). The result is\nwritten to the destination register (rd), and the source operand is the\nregister specified by rs1. The format is common for shift-left logical\nimmediate (SLLI), shift-right logical immediate (SRLI), and shift-right\narithmetic immediate (SRAI) operations.\n *\nNote: For RV32, the decoder ensures that shamt[5] = 0.\n " }, { "mnemonic": "slli.uw", "name": "TBD", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b000010", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [ "Zba" ], "function": "{\n let rs1_val = X(rs1);\n let result : xlenbits = zero_extend(rs1_val[31..0]) << shamt;\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "slliw", "name": "Shift Immediate Word", "operands": [ { "name": "shamt", "type": "bits(5)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "sopw" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "shamt", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let result : bits(32) = match op {\n RISCV_SLLIW => rs1_val << shamt,\n RISCV_SRLIW => rs1_val >> shamt,\n RISCV_SRAIW => shift_right_arith32(rs1_val, shamt)\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe SHIFTIWOP instruction set deals with\nimmediate shift operations on 32-bit values, with the result sign-extended\nto 64 bits. The available operations include SLLIW (left shift logical\nimmediate word), SRLIW (right shift logical immediate word), and SRAIW\n(right shift arithmetic immediate word). These operations are applicable\nwhen the target architecture has a width of 64 bits.\n " }, { "mnemonic": "sllw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "ropw" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let rs2_val = (X(rs2))[31..0];\n let result : bits(32) = match op {\n RISCV_ADDW => rs1_val + rs2_val,\n RISCV_SUBW => rs1_val - rs2_val,\n RISCV_SLLW => rs1_val << (rs2_val[4..0]),\n RISCV_SRLW => rs1_val >> (rs2_val[4..0]),\n RISCV_SRAW => shift_right_arith32(rs1_val, rs2_val[4..0])\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe RTYPEW instruction set operates on 32-bit values,\nand the result is sign-extended to 64 bits. The available operations are\nADDW (addition), SUBW (subtraction), SLLW (logical left shift),\nSRLW (logical right shift), and SRAW (arithmetic right shift).\nThese operations are only applicable when the width of the target\narchitecture is 64 bits.\n " }, { "mnemonic": "slt", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "slti", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "iop" } ], "syntax": "rd,rs1,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "encdec_iop(op)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let immext : xlenbits = sign_extend(imm);\n let result : xlenbits = match op {\n RISCV_ADDI => rs1_val + immext,\n RISCV_SLTI => zero_extend(bool_to_bits(rs1_val <_s immext)),\n RISCV_SLTIU => zero_extend(bool_to_bits(rs1_val <_u immext)),\n RISCV_ANDI => rs1_val & immext,\n RISCV_ORI => rs1_val | immext,\n RISCV_XORI => rs1_val ^ immext\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe ITYPE instruction operates on an immediate value, adding, comparing, or\nperforming bitwise operations with the contents of register rs1.\nThe immediate value, rs1, and the operation code (iop) determine the operation.\nThe result is stored in register rd.\nThe supported immediate operations (iop) include:\n - \"addi\" : Add immediate\n - \"slti\" : Set less than immediate (signed)\n - \"sltiu\" : Set less than immediate (unsigned)\n - \"andi\" : AND immediate\n - \"ori\" : OR immediate\n - \"xori\" : XOR immediate\n *\nNote: The immediate value is sign-extended before performing the operation.\n " }, { "mnemonic": "sltiu", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "iop" } ], "syntax": "rd,rs1,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "encdec_iop(op)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let immext : xlenbits = sign_extend(imm);\n let result : xlenbits = match op {\n RISCV_ADDI => rs1_val + immext,\n RISCV_SLTI => zero_extend(bool_to_bits(rs1_val <_s immext)),\n RISCV_SLTIU => zero_extend(bool_to_bits(rs1_val <_u immext)),\n RISCV_ANDI => rs1_val & immext,\n RISCV_ORI => rs1_val | immext,\n RISCV_XORI => rs1_val ^ immext\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe ITYPE instruction operates on an immediate value, adding, comparing, or\nperforming bitwise operations with the contents of register rs1.\nThe immediate value, rs1, and the operation code (iop) determine the operation.\nThe result is stored in register rd.\nThe supported immediate operations (iop) include:\n - \"addi\" : Add immediate\n - \"slti\" : Set less than immediate (signed)\n - \"sltiu\" : Set less than immediate (unsigned)\n - \"andi\" : AND immediate\n - \"ori\" : OR immediate\n - \"xori\" : XOR immediate\n *\nNote: The immediate value is sign-extended before performing the operation.\n " }, { "mnemonic": "sltu", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "sm3p0", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zksh" ], "function": "{\n let r1 : bits(32) = X(rs1)[31..0];\n let result : bits(32) = r1 ^ (r1 <<< 9) ^ (r1 <<< 17);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sm3p1", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b00", "size": 2 }, { "field": "0b01000", "size": 5 }, { "field": "0b01001", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zksh" ], "function": "{\n let r1 : bits(32) = X(rs1)[31..0];\n let result : bits(32) = r1 ^ (r1 <<< 15) ^ (r1 <<< 23);\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sm4ed", "name": "TBD", "operands": [ { "name": "bs", "type": "bits(2)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2,bs", "format": "TBD", "fields": [ { "field": "bs", "size": 2 }, { "field": "0b11000", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zksed" ], "function": "{\n let shamt : bits(5) = bs @ 0b000; /* shamt = bs*8 */\n let sb_in : bits(8) = (X(rs2)[31..0] >> shamt)[7..0];\n let x : bits(32) = 0x000000 @ sm4_sbox(sb_in);\n let y : bits(32) = x ^ (x << 8) ^ ( x << 2) ^\n (x << 18) ^ ((x & 0x0000003F) << 26) ^\n ((x & 0x000000C0) << 10);\n let z : bits(32) = (y <<< shamt);\n let result : bits(32) = z ^ X(rs1)[31..0];\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sm4ks", "name": "TBD", "operands": [ { "name": "bs", "type": "bits(2)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2,bs", "format": "TBD", "fields": [ { "field": "bs", "size": 2 }, { "field": "0b11010", "size": 5 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zksed" ], "function": "{\n let shamt : bits(5) = (bs @ 0b000); /* shamt = bs*8 */\n let sb_in : bits(8) = (X(rs2)[31..0] >> shamt)[7..0];\n let x : bits(32) = 0x000000 @ sm4_sbox(sb_in);\n let y : bits(32) = x ^ ((x & 0x00000007) << 29) ^ ((x & 0x000000FE) << 7) ^\n ((x & 0x00000001) << 23) ^ ((x & 0x000000F8) << 13) ;\n let z : bits(32) = (y <<< shamt);\n let result : bits(32) = z ^ X(rs1)[31..0];\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "sra", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "srai", "name": "Shift Immediate", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "sop" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n /* the decoder guard should ensure that shamt[5] = 0 for RV32 */\n let result : xlenbits = match op {\n RISCV_SLLI => if sizeof(xlen) == 32\n then rs1_val << shamt[4..0]\n else rs1_val << shamt,\n RISCV_SRLI => if sizeof(xlen) == 32\n then rs1_val >> shamt[4..0]\n else rs1_val >> shamt,\n RISCV_SRAI => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, shamt[4..0])\n else shift_right_arith64(rs1_val, shamt)\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe SHIFTIOP (Shift Immediate Operation) instruction format is used for\noperations that involve shifting the bits of a register by an immediate\nvalue. The specific operation is determined by the opcode field, and the\nshift amount is specified by the immediate value (shamt). The result is\nwritten to the destination register (rd), and the source operand is the\nregister specified by rs1. The format is common for shift-left logical\nimmediate (SLLI), shift-right logical immediate (SRLI), and shift-right\narithmetic immediate (SRAI) operations.\n *\nNote: For RV32, the decoder ensures that shamt[5] = 0.\n " }, { "mnemonic": "sraiw", "name": "Shift Immediate Word", "operands": [ { "name": "shamt", "type": "bits(5)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "sopw" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "shamt", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let result : bits(32) = match op {\n RISCV_SLLIW => rs1_val << shamt,\n RISCV_SRLIW => rs1_val >> shamt,\n RISCV_SRAIW => shift_right_arith32(rs1_val, shamt)\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe SHIFTIWOP instruction set deals with\nimmediate shift operations on 32-bit values, with the result sign-extended\nto 64 bits. The available operations include SLLIW (left shift logical\nimmediate word), SRLIW (right shift logical immediate word), and SRAIW\n(right shift arithmetic immediate word). These operations are applicable\nwhen the target architecture has a width of 64 bits.\n " }, { "mnemonic": "sraw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "ropw" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let rs2_val = (X(rs2))[31..0];\n let result : bits(32) = match op {\n RISCV_ADDW => rs1_val + rs2_val,\n RISCV_SUBW => rs1_val - rs2_val,\n RISCV_SLLW => rs1_val << (rs2_val[4..0]),\n RISCV_SRLW => rs1_val >> (rs2_val[4..0]),\n RISCV_SRAW => shift_right_arith32(rs1_val, rs2_val[4..0])\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe RTYPEW instruction set operates on 32-bit values,\nand the result is sign-extended to 64 bits. The available operations are\nADDW (addition), SUBW (subtraction), SLLW (logical left shift),\nSRLW (logical right shift), and SRAW (arithmetic right shift).\nThese operations are only applicable when the width of the target\narchitecture is 64 bits.\n " }, { "mnemonic": "sret", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b0001000", "size": 7 }, { "field": "0b00010", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n let sret_illegal : bool = match cur_privilege {\n User => true,\n Supervisor => not(haveSupMode ()) | mstatus.TSR() == 0b1,\n Machine => not(haveSupMode ())\n };\n if sret_illegal\n then { handle_illegal(); RETIRE_FAIL }\n else if not(ext_check_xret_priv (Supervisor))\n then { ext_fail_xret_priv(); RETIRE_FAIL }\n else {\n set_next_pc(exception_handler(cur_privilege, CTL_SRET(), PC));\n RETIRE_SUCCESS\n }\n}", "description": "TBD" }, { "mnemonic": "srl", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "srli", "name": "Shift Immediate", "operands": [ { "name": "shamt", "type": "bits(6)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "sop" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "shamt", "size": 6 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n /* the decoder guard should ensure that shamt[5] = 0 for RV32 */\n let result : xlenbits = match op {\n RISCV_SLLI => if sizeof(xlen) == 32\n then rs1_val << shamt[4..0]\n else rs1_val << shamt,\n RISCV_SRLI => if sizeof(xlen) == 32\n then rs1_val >> shamt[4..0]\n else rs1_val >> shamt,\n RISCV_SRAI => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, shamt[4..0])\n else shift_right_arith64(rs1_val, shamt)\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe SHIFTIOP (Shift Immediate Operation) instruction format is used for\noperations that involve shifting the bits of a register by an immediate\nvalue. The specific operation is determined by the opcode field, and the\nshift amount is specified by the immediate value (shamt). The result is\nwritten to the destination register (rd), and the source operand is the\nregister specified by rs1. The format is common for shift-left logical\nimmediate (SLLI), shift-right logical immediate (SRLI), and shift-right\narithmetic immediate (SRAI) operations.\n *\nNote: For RV32, the decoder ensures that shamt[5] = 0.\n " }, { "mnemonic": "srliw", "name": "Shift Immediate Word", "operands": [ { "name": "shamt", "type": "bits(5)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "sopw" } ], "syntax": "rd,rs1,shamt", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "shamt", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0011011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let result : bits(32) = match op {\n RISCV_SLLIW => rs1_val << shamt,\n RISCV_SRLIW => rs1_val >> shamt,\n RISCV_SRAIW => shift_right_arith32(rs1_val, shamt)\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe SHIFTIWOP instruction set deals with\nimmediate shift operations on 32-bit values, with the result sign-extended\nto 64 bits. The available operations include SLLIW (left shift logical\nimmediate word), SRLIW (right shift logical immediate word), and SRAIW\n(right shift arithmetic immediate word). These operations are applicable\nwhen the target architecture has a width of 64 bits.\n " }, { "mnemonic": "srlw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "ropw" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let rs2_val = (X(rs2))[31..0];\n let result : bits(32) = match op {\n RISCV_ADDW => rs1_val + rs2_val,\n RISCV_SUBW => rs1_val - rs2_val,\n RISCV_SLLW => rs1_val << (rs2_val[4..0]),\n RISCV_SRLW => rs1_val >> (rs2_val[4..0]),\n RISCV_SRAW => shift_right_arith32(rs1_val, rs2_val[4..0])\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe RTYPEW instruction set operates on 32-bit values,\nand the result is sign-extended to 64 bits. The available operations are\nADDW (addition), SUBW (subtraction), SLLW (logical left shift),\nSRLW (logical right shift), and SRAW (arithmetic right shift).\nThese operations are only applicable when the width of the target\narchitecture is 64 bits.\n " }, { "mnemonic": "sub", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "subw", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "ropw" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = (X(rs1))[31..0];\n let rs2_val = (X(rs2))[31..0];\n let result : bits(32) = match op {\n RISCV_ADDW => rs1_val + rs2_val,\n RISCV_SUBW => rs1_val - rs2_val,\n RISCV_SLLW => rs1_val << (rs2_val[4..0]),\n RISCV_SRLW => rs1_val >> (rs2_val[4..0]),\n RISCV_SRAW => shift_right_arith32(rs1_val, rs2_val[4..0])\n };\n X(rd) = sign_extend(result);\n RETIRE_SUCCESS\n}", "description": "\nThe RTYPEW instruction set operates on 32-bit values,\nand the result is sign-extended to 64 bits. The available operations are\nADDW (addition), SUBW (subtraction), SLLW (logical left shift),\nSRLW (logical right shift), and SRAW (arithmetic right shift).\nThese operations are only applicable when the width of the target\narchitecture is 64 bits.\n " }, { "mnemonic": "sw", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sw.aq", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sw.aq.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "sw.rl", "name": "Store", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "word_width" }, { "name": "aq", "type": "bool" }, { "name": "rl", "type": "bool" } ], "syntax": "rs2,imm(rs1)", "format": "TBD", "fields": [ { "field": "imm7", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b0", "size": 1 }, { "field": "size_bits(size)", "size": 2 }, { "field": "imm5", "size": 1 }, { "field": "0b0100011", "size": 7 } ], "extensions": [], "function": "{\n let offset : xlenbits = sign_extend(imm);\n /* Get the address, X(rs1) + offset.\n Some extensions perform additional checks on address validity. */\n match ext_data_get_addr(rs1, offset, Write(Data), width) {\n Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },\n Ext_DataAddr_OK(vaddr) =>\n if check_misaligned(vaddr, width)\n then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }\n else match translateAddr(vaddr, Write(Data)) {\n TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n TR_Address(paddr, _) => {\n let eares : MemoryOpResult(unit) = match width {\n BYTE => mem_write_ea(paddr, 1, aq, rl, false),\n HALF => mem_write_ea(paddr, 2, aq, rl, false),\n WORD => mem_write_ea(paddr, 4, aq, rl, false),\n DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)\n };\n match (eares) {\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },\n MemValue(_) => {\n let rs2_val = X(rs2);\n let res : MemoryOpResult(bool) = match (width) {\n BYTE => mem_write_value(paddr, 1, rs2_val[7..0], aq, rl, false),\n HALF => mem_write_value(paddr, 2, rs2_val[15..0], aq, rl, false),\n WORD => mem_write_value(paddr, 4, rs2_val[31..0], aq, rl, false),\n DOUBLE if sizeof(xlen) >= 64\n => mem_write_value(paddr, 8, rs2_val, aq, rl, false),\n _ => report_invalid_width(__FILE__, __LINE__, width, \"store\"),\n };\n match (res) {\n MemValue(true) => RETIRE_SUCCESS,\n MemValue(false) => internal_error(__FILE__, __LINE__, \"store got false from mem_write_value\"),\n MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }\n }\n }\n }\n }\n }\n }\n}", "description": "\nThe STORE instruction format is used for storing data from a register into\nmemory. The specific operation is determined by the word width (size) and\nmemory ordering semantics (acquire, release). The memory address is computed\nby adding the immediate offset (imm) to the value in register rs1, and the\ndata is taken from register rs2.\n " }, { "mnemonic": "unzip", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b000010001111", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbkb" ], "function": "{\n assert(sizeof(xlen) == 32);\n let rs1_val = X(rs1);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen_bytes)*4 - 1)) {\n result[i] = rs1_val[i*2];\n result[i + sizeof(xlen_bytes)*4] = rs1_val[i*2 + 1];\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "uret", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b0000000", "size": 7 }, { "field": "0b00010", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "{\n if not(haveUsrMode()) | not(sys_enable_next())\n then handle_illegal()\n else if not(ext_check_xret_priv(User))\n then ext_fail_xret_priv()\n else set_next_pc(exception_handler(cur_privilege, CTL_URET(), PC));\n RETIRE_FAIL\n}", "description": "TBD" }, { "mnemonic": "vaadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vaadd.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vaaddu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vaaddu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vadc.vim", "name": "TBD", "operands": [ { "name": "funct6", "type": "vimsfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simm,v0", "format": "TBD", "fields": [ { "field": "encdec_vimsfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n /* for bypassing normal masking in init_masked_result */\n vec_trues : vector('n, dec, bool) = undefined;\n foreach (i from 0 to (num_elem - 1)) {\n vec_trues[i] = true\n };\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vec_trues);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VIMS_VADC => to_bits(SEW, unsigned(vs2_val[i]) + unsigned(imm_val) + unsigned(bool_to_bits(vm_val[i])))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vadc.vvm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvmsfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vvmsfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n /* for bypassing normal masking in init_masked_result */\n vec_trues : vector('n, dec, bool) = undefined;\n foreach (i from 0 to (num_elem - 1)) {\n vec_trues[i] = true\n };\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vec_trues);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VVMS_VADC => to_bits(SEW, unsigned(vs2_val[i]) + unsigned(vs1_val[i]) + unsigned(bool_to_bits(vm_val[i]))),\n VVMS_VSBC => to_bits(SEW, unsigned(vs2_val[i]) - unsigned(vs1_val[i]) - unsigned(bool_to_bits(vm_val[i])))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vadc.vxm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxmsfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vxmsfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n /* for bypassing normal masking in init_masked_result */\n vec_trues : vector('n, dec, bool) = undefined;\n foreach (i from 0 to (num_elem - 1)) {\n vec_trues[i] = true\n };\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vec_trues);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VXMS_VADC => to_bits(SEW, unsigned(vs2_val[i]) + unsigned(rs1_val) + unsigned(bool_to_bits(vm_val[i]))),\n VXMS_VSBC => to_bits(SEW, unsigned(vs2_val[i]) - unsigned(rs1_val) - unsigned(bool_to_bits(vm_val[i])))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vadd.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vadd.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vand.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vand.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vand.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vasub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vasub.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vasubu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vasubu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vcompress.vm", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let end_element = get_end_element();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n /* vcompress should always be executed with a vstart of 0 */\n if start_element != 0 | vs1 == vd | vs2 == vd | illegal_vd_unmasked()\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n /* body elements */\n vd_idx : nat = 0;\n foreach (i from 0 to (num_elem - 1)) {\n if i <= end_element then {\n if vs1_val[i] then {\n let 'p = vd_idx;\n assert('p < 'n);\n result['p] = vs2_val[i];\n vd_idx = vd_idx + 1;\n }\n }\n };\n /* tail elements */\n if vd_idx < num_elem then {\n let tail_ag : agtype = get_vtype_vta();\n let 'p = vd_idx;\n foreach (i from 'p to (num_elem - 1)) {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vdiv.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vdiv.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vdivu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vdivu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfadd.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfclass.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary1", "type": "vfunary1" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010011", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary1_vs1(vfunary1)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary1 {\n FVV_VSQRT => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Sqrt(rm_3b, vs2_val[i]),\n 32 => riscv_f32Sqrt(rm_3b, vs2_val[i]),\n 64 => riscv_f64Sqrt(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VRSQRT7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Rsqrte7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Rsqrte7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Rsqrte7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VREC7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Recip7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Recip7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Recip7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VCLASS => fp_class(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfcvt.f.x.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary0", "type": "vfunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary0_vs1(vfunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary0 {\n FV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_ui64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_i64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi32(0b001, vs2_val[i]),\n 64 => riscv_f64ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(0b001, vs2_val[i]),\n 32 => riscv_f32ToI32(0b001, vs2_val[i]),\n 64 => riscv_f64ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfcvt.f.xu.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary0", "type": "vfunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary0_vs1(vfunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary0 {\n FV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_ui64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_i64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi32(0b001, vs2_val[i]),\n 64 => riscv_f64ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(0b001, vs2_val[i]),\n 32 => riscv_f32ToI32(0b001, vs2_val[i]),\n 64 => riscv_f64ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfcvt.rtz.x.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary0", "type": "vfunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary0_vs1(vfunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary0 {\n FV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_ui64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_i64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi32(0b001, vs2_val[i]),\n 64 => riscv_f64ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(0b001, vs2_val[i]),\n 32 => riscv_f32ToI32(0b001, vs2_val[i]),\n 64 => riscv_f64ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfcvt.rtz.xu.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary0", "type": "vfunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary0_vs1(vfunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary0 {\n FV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_ui64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_i64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi32(0b001, vs2_val[i]),\n 64 => riscv_f64ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(0b001, vs2_val[i]),\n 32 => riscv_f32ToI32(0b001, vs2_val[i]),\n 64 => riscv_f64ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfcvt.x.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary0", "type": "vfunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary0_vs1(vfunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary0 {\n FV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_ui64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_i64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi32(0b001, vs2_val[i]),\n 64 => riscv_f64ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(0b001, vs2_val[i]),\n 32 => riscv_f32ToI32(0b001, vs2_val[i]),\n 64 => riscv_f64ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfcvt.xu.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary0", "type": "vfunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary0_vs1(vfunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary0 {\n FV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI32(rm_3b, vs2_val[i]),\n 64 => riscv_f64ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_ui64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF32(rm_3b, vs2_val[i]),\n 64 => riscv_i64ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi32(0b001, vs2_val[i]),\n 64 => riscv_f64ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16ToI16(0b001, vs2_val[i]),\n 32 => riscv_f32ToI32(0b001, vs2_val[i]),\n 64 => riscv_f64ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfdiv.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfdiv.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfirst.m", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b10001", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() | not(assert_vstart(0)) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, 0, vs2_val, vm_val);\n\n index : int = -1;\n foreach (i from 0 to (num_elem - 1)) {\n if index == -1 then {\n if mask[i] & vs2_val[i] then index = i;\n };\n };\n\n X(rd) = to_bits(sizeof(xlen), index);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmacc.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmacc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmadd.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmax.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmax.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmerge.vfm", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1,v0", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let start_element = get_start_element();\n let end_element = get_end_element();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW); /* max(VLMAX,VLEN/SEW)) */\n let real_num_elem = if LMUL_pow >= 0 then num_elem else num_elem / (0 - LMUL_pow); /* VLMAX */\n\n if illegal_fp_vd_masked(vd, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n let tail_ag : agtype = get_vtype_vta();\n foreach (i from 0 to (num_elem - 1)) {\n if i < start_element then {\n result[i] = vd_val[i]\n } else if i > end_element | i >= real_num_elem then {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n } else {\n /* the merge operates on all body elements */\n result[i] = if vm_val[i] then rs1_val else vs2_val[i]\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmin.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmin.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmsac.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmsac.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmsub.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmul.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmul.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmv.f.s", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,vs2", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let num_elem = get_num_elem(0, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) | SEW > sizeof(flen)\n then { handle_illegal(); return RETIRE_FAIL };\n assert(num_elem > 0 & SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, 0, vs2);\n match 'm {\n 16 => F_H(rd) = vs2_val[0],\n 32 => F_S(rd) = vs2_val[0],\n 64 => F_D(rd) = vs2_val[0]\n };\n vstart = zeros();\n\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmv.s.f", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let num_elem = get_num_elem(0, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(num_elem > 0 & SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, 0, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, 0, vd_val, vm_val);\n\n /* one body element */\n if mask[0] then result[0] = rs1_val;\n\n /* others treated as tail elements */\n let tail_ag : agtype = get_vtype_vta();\n foreach (i from 1 to (num_elem - 1)) {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n };\n\n write_vreg(num_elem, SEW, 0, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfmv.v.f", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then result[i] = rs1_val\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.f.f.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.f.x.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.f.xu.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.rod.f.f.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.rtz.x.f.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.rtz.xu.f.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.x.f.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfncvt.xu.f.w", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfnunary0", "type": "vfnunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfnunary0_vs1(vfnunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfnunary0 {\n FNV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToUi16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToUi32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(rm_3b, vs2_val[i]),\n 16 => riscv_f32ToI16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToI32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_ui32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_ui64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_i32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_i64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(rm_3b, vs2_val[i]),\n 32 => riscv_f64ToF32(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_ROD_F_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f32ToF16(0b110, vs2_val[i]),\n 32 => riscv_f64ToF32(0b110, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToUi8(0b001, vs2_val[i]),\n 16 => riscv_f32ToUi16(0b001, vs2_val[i]),\n 32 => riscv_f64ToUi32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FNV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 8 => riscv_f16ToI8(0b001, vs2_val[i]),\n 16 => riscv_f32ToI16(0b001, vs2_val[i]),\n 32 => riscv_f64ToI32(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmacc.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmacc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmadd.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmsac.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmsac.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmsub.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VMACC => fp_muladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMACC => fp_nmulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMSAC => fp_mulsub(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VNMSAC => fp_nmuladd(rm_3b, rs1_val, vs2_val[i], vd_val[i]),\n VF_VMADD => fp_muladd(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMADD => fp_nmulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VMSUB => fp_mulsub(rm_3b, rs1_val, vd_val[i], vs2_val[i]),\n VF_VNMSUB => fp_nmuladd(rm_3b, rs1_val, vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfnmsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VMACC => fp_muladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMACC => fp_nmulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMSAC => fp_mulsub(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VNMSAC => fp_nmuladd(rm_3b, vs1_val[i], vs2_val[i], vd_val[i]),\n FVV_VMADD => fp_muladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMADD => fp_nmulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VMSUB => fp_mulsub(rm_3b, vs1_val[i], vd_val[i], vs2_val[i]),\n FVV_VNMSUB => fp_nmuladd(rm_3b, vs1_val[i], vd_val[i], vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfrdiv.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfrec7.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary1", "type": "vfunary1" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010011", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary1_vs1(vfunary1)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary1 {\n FVV_VSQRT => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Sqrt(rm_3b, vs2_val[i]),\n 32 => riscv_f32Sqrt(rm_3b, vs2_val[i]),\n 64 => riscv_f64Sqrt(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VRSQRT7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Rsqrte7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Rsqrte7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Rsqrte7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VREC7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Recip7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Recip7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Recip7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VCLASS => fp_class(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfredmax.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rfvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rfvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n\n if funct6 == FVV_VFWREDOSUM | funct6 == FVV_VFWREDUSUM then\n process_rfvv_widen(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n else\n process_rfvv_single(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n}", "description": "TBD" }, { "mnemonic": "vfredmin.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rfvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rfvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n\n if funct6 == FVV_VFWREDOSUM | funct6 == FVV_VFWREDUSUM then\n process_rfvv_widen(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n else\n process_rfvv_single(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n}", "description": "TBD" }, { "mnemonic": "vfredosum.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rfvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rfvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n\n if funct6 == FVV_VFWREDOSUM | funct6 == FVV_VFWREDUSUM then\n process_rfvv_widen(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n else\n process_rfvv_single(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n}", "description": "TBD" }, { "mnemonic": "vfredusum.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rfvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rfvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n\n if funct6 == FVV_VFWREDOSUM | funct6 == FVV_VFWREDUSUM then\n process_rfvv_widen(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n else\n process_rfvv_single(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n}", "description": "TBD" }, { "mnemonic": "vfrsqrt7.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary1", "type": "vfunary1" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010011", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary1_vs1(vfunary1)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary1 {\n FVV_VSQRT => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Sqrt(rm_3b, vs2_val[i]),\n 32 => riscv_f32Sqrt(rm_3b, vs2_val[i]),\n 64 => riscv_f64Sqrt(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VRSQRT7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Rsqrte7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Rsqrte7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Rsqrte7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VREC7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Recip7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Recip7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Recip7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VCLASS => fp_class(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfrsub.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsgnj.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsgnj.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsgnjn.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsgnjn.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsgnjx.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsgnjx.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfslide1down.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfslide1up.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsqrt.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfunary1", "type": "vfunary1" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010011", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfunary1_vs1(vfunary1)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfunary1 {\n FVV_VSQRT => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Sqrt(rm_3b, vs2_val[i]),\n 32 => riscv_f32Sqrt(rm_3b, vs2_val[i]),\n 64 => riscv_f64Sqrt(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VRSQRT7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Rsqrte7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Rsqrte7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Rsqrte7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VREC7 => {\n let (fflags, elem) : (bits_fflags, bits('m)) = match 'm {\n 16 => riscv_f16Recip7(rm_3b, vs2_val[i]),\n 32 => riscv_f32Recip7(rm_3b, vs2_val[i]),\n 64 => riscv_f64Recip7(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FVV_VCLASS => fp_class(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsub.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VF_VADD => fp_add(rm_3b, vs2_val[i], rs1_val),\n VF_VSUB => fp_sub(rm_3b, vs2_val[i], rs1_val),\n VF_VRSUB => fp_sub(rm_3b, rs1_val, vs2_val[i]),\n VF_VMIN => fp_min(vs2_val[i], rs1_val),\n VF_VMAX => fp_max(vs2_val[i], rs1_val),\n VF_VMUL => fp_mul(rm_3b, vs2_val[i], rs1_val),\n VF_VDIV => fp_div(rm_3b, vs2_val[i], rs1_val),\n VF_VRDIV => fp_div(rm_3b, rs1_val, vs2_val[i]),\n VF_VSGNJ => [rs1_val['m - 1]] @ vs2_val[i][('m - 2)..0],\n VF_VSGNJN => (0b1 ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSGNJX => ([vs2_val[i]['m - 1]] ^ [rs1_val['m - 1]]) @ vs2_val[i][('m - 2)..0],\n VF_VSLIDE1UP => {\n if vs2 == vd then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n VF_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_normal(vd, vm, SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FVV_VADD => fp_add(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSUB => fp_sub(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VMIN => fp_min(vs2_val[i], vs1_val[i]),\n FVV_VMAX => fp_max(vs2_val[i], vs1_val[i]),\n FVV_VMUL => fp_mul(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VDIV => fp_div(rm_3b, vs2_val[i], vs1_val[i]),\n FVV_VSGNJ => [vs1_val[i]['m - 1]] @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJN => (0b1 ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0],\n FVV_VSGNJX => ([vs2_val[i]['m - 1]] ^ [vs1_val[i]['m - 1]]) @ vs2_val[i][('m - 2)..0]\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwadd.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VADD => fp_add(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val)),\n FWVF_VSUB => fp_sub(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val)),\n FWVF_VMUL => fp_mul(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VADD => fp_add(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i])),\n FWVV_VSUB => fp_sub(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i])),\n FWVV_VMUL => fp_mul(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwadd.wf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen)\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWF_VADD => fp_add(rm_3b, vs2_val[i], fp_widen(rs1_val)),\n FWF_VSUB => fp_sub(rm_3b, vs2_val[i], fp_widen(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwadd.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWV_VADD => fp_add(rm_3b, vs2_val[i], fp_widen(vs1_val[i])),\n FWV_VSUB => fp_sub(rm_3b, vs2_val[i], fp_widen(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.f.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.f.x.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.f.xu.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.rtz.x.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.rtz.xu.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.x.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwcvt.xu.f.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vfwunary0", "type": "vfwunary0" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "encdec_vfwunary0_vs1(vfwunary0)", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 8 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match vfwunary0 {\n FWV_CVT_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToUi64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToI64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_XU => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_ui32ToF16(rm_3b, zero_extend(vs2_val[i])),\n 16 => riscv_ui32ToF32(rm_3b, zero_extend(vs2_val[i])),\n 32 => riscv_ui32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_X => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => riscv_i32ToF16(rm_3b, sign_extend(vs2_val[i])),\n 16 => riscv_i32ToF32(rm_3b, sign_extend(vs2_val[i])),\n 32 => riscv_i32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_F_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToF32(rm_3b, vs2_val[i]),\n 32 => riscv_f32ToF64(rm_3b, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_XU_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToUi32(0b001, vs2_val[i]),\n 32 => riscv_f32ToUi64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n },\n FWV_CVT_RTZ_X_F => {\n let (fflags, elem) : (bits_fflags, bits('o)) = match 'm {\n 8 => { handle_illegal(); return RETIRE_FAIL },\n 16 => riscv_f16ToI32(0b001, vs2_val[i]),\n 32 => riscv_f32ToI64(0b001, vs2_val[i])\n };\n accrue_fflags(fflags);\n elem\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwmacc.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VMACC => fp_muladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMACC => fp_nmulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VMSAC => fp_mulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMSAC => fp_nmuladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwmacc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs1", "size": 5 }, { "field": "vs2", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VMACC => fp_muladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMACC => fp_nmulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VMSAC => fp_mulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMSAC => fp_nmuladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwmsac.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VMACC => fp_muladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMACC => fp_nmulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VMSAC => fp_mulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMSAC => fp_nmuladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwmsac.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs1", "size": 5 }, { "field": "vs2", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VMACC => fp_muladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMACC => fp_nmulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VMSAC => fp_mulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMSAC => fp_nmuladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwmul.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VADD => fp_add(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val)),\n FWVF_VSUB => fp_sub(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val)),\n FWVF_VMUL => fp_mul(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwmul.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VADD => fp_add(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i])),\n FWVV_VSUB => fp_sub(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i])),\n FWVV_VMUL => fp_mul(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwnmacc.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VMACC => fp_muladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMACC => fp_nmulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VMSAC => fp_mulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMSAC => fp_nmuladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwnmacc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs1", "size": 5 }, { "field": "vs2", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VMACC => fp_muladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMACC => fp_nmulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VMSAC => fp_mulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMSAC => fp_nmuladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwnmsac.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvfmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvfmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VMACC => fp_muladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMACC => fp_nmulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VMSAC => fp_mulsub(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i]),\n FWVF_VNMSAC => fp_nmuladd(rm_3b, fp_widen(rs1_val), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwnmsac.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs1", "type": "regidx" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs1", "size": 5 }, { "field": "vs2", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VMACC => fp_muladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMACC => fp_nmulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VMSAC => fp_mulsub(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i]),\n FWVV_VNMSAC => fp_nmuladd(rm_3b, fp_widen(vs1_val[i]), fp_widen(vs2_val[i]), vd_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwredosum.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rfvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rfvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n\n if funct6 == FVV_VFWREDOSUM | funct6 == FVV_VFWREDUSUM then\n process_rfvv_widen(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n else\n process_rfvv_single(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n}", "description": "TBD" }, { "mnemonic": "vfwredusum.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rfvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rfvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n\n if funct6 == FVV_VFWREDOSUM | funct6 == FVV_VFWREDUSUM then\n process_rfvv_widen(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n else\n process_rfvv_single(funct6, vm, vs2, vs1, vd, num_elem_vs, SEW, LMUL_pow)\n}", "description": "TBD" }, { "mnemonic": "vfwsub.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVF_VADD => fp_add(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val)),\n FWVF_VSUB => fp_sub(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val)),\n FWVF_VMUL => fp_mul(rm_3b, fp_widen(vs2_val[i]), fp_widen(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWVV_VADD => fp_add(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i])),\n FWVV_VSUB => fp_sub(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i])),\n FWVV_VMUL => fp_mul(rm_3b, fp_widen(vs2_val[i]), fp_widen(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwsub.wf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwffunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwffunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen)\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWF_VADD => fp_add(rm_3b, vs2_val[i], fp_widen(rs1_val)),\n FWF_VSUB => fp_sub(rm_3b, vs2_val[i], fp_widen(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vfwsub.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fwvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fwvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_fp_variable_width(vd, vm, SEW, rm_3b, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW >= 16 & SEW_widen <= 64);\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n FWV_VADD => fp_add(rm_3b, vs2_val[i], fp_widen(vs1_val[i])),\n FWV_VSUB => fp_sub(rm_3b, vs2_val[i], fp_widen(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vid.v", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vdvm", "format": "TBD", "fields": [ { "field": "0b010100", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "0b10001", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then result[i] = to_bits(SEW, i)\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "viota.m", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010100", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b10000", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) | not(assert_vstart(0)) | vd == vs2\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n sum : int = 0;\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = to_bits(SEW, sum);\n if vs2_val[i] then sum = sum + 1\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vle16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vle8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlm.v", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "vd_or_vs3", "type": "regidx" }, { "name": "op", "type": "vmlsop" } ], "syntax": "vd_or_vs3,(rs1)", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd_or_vs3", "size": 5 }, { "field": "encdec_lsop(op)", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW = 8;\n let EMUL_pow = 0;\n let vl_val = unsigned(vl);\n let evl : int = if vl_val % 8 == 0 then vl_val / 8 else vl_val / 8 + 1; /* the effective vector length is evl=ceil(vl/8) */\n let num_elem = get_num_elem(EMUL_pow, EEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n assert(evl >= 0);\n process_vm(vd_or_vs3, rs1, num_elem, evl, op)\n}", "description": "TBD" }, { "mnemonic": "vloxei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg2ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg2ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg2ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg2ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg3ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg3ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg3ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg3ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg4ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg4ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg4ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg4ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg5ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg5ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg5ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg5ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg6ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg6ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg6ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg6ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg7ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg7ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg7ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg7ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg8ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg8ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg8ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vloxseg8ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b11", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 3)\n}", "description": "TBD" }, { "mnemonic": "vlre16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlre32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlre64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlre8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlse16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlse32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlse64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlse8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg2re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg2re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg2re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg2re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg3re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg3re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg3re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg3re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg4re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg4re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg4re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg4re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg5re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg5re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg5re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg5re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg6re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg6re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg6re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg6re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg7re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg7re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg7re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg7re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e16ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e32ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e64ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW); /* # of element of each register group */\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlseg(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8e8ff.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b10000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsegff(nf_int, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlseg8re16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg8re32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg8re64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlseg8re8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlre(nf_int, vd, load_width_bytes, rs1, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vlsseg2e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg2e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg2e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg2e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg3e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg3e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg3e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg3e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg4e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg4e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg4e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg4e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg5e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg5e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg5e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg5e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg6e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg6e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg6e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg6e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg7e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg7e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg7e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg7e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg8e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg8e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg8e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vlsseg8e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_load(vd, vm, nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlsseg(nf_int, vm, vd, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vluxei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg2ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg2ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg2ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg2ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg3ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg3ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg3ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg3ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg4ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg4ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg4ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg4ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg5ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg5ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg5ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg5ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg6ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg6ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg6ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg6ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg7ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg7ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg7ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg7ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg8ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg8ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg8ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vluxseg8ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b0000111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8);\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_load(vd, vm, nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vlxseg(nf_int, vm, vd, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vmacc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VMACC => get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0) + vd_val[i],\n MVV_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0),\n MVV_VMADD => get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0) + vs2_val[i],\n MVV_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmacc.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvxmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VMACC => get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0) + vd_val[i],\n MVX_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0),\n MVX_VMADD => get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0) + vs2_val[i],\n MVX_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadc.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vimcfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simm", "format": "TBD", "fields": [ { "field": "encdec_vimcfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VIMC_VMADC => unsigned(vs2_val[i]) + unsigned(imm_val) > 2 ^ SEW - 1\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadc.vim", "name": "TBD", "operands": [ { "name": "funct6", "type": "vimfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simm,v0", "format": "TBD", "fields": [ { "field": "encdec_vimfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VIM_VMADC => unsigned(vs2_val[i]) + unsigned(imm_val) + unsigned(bool_to_bits(vm_val[i])) > 2 ^ SEW - 1\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvmcfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_vvmcfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVMC_VMADC => unsigned(vs2_val[i]) + unsigned(vs1_val[i]) > 2 ^ SEW - 1,\n VVMC_VMSBC => unsigned(vs2_val[i]) - unsigned(vs1_val[i]) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadc.vvm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vvmfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVM_VMADC => unsigned(vs2_val[i]) + unsigned(vs1_val[i]) + unsigned(bool_to_bits(vm_val[i])) > 2 ^ SEW - 1,\n VVM_VMSBC => unsigned(vs2_val[i]) - unsigned(vs1_val[i]) - unsigned(bool_to_bits(vm_val[i])) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadc.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxmcfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1", "format": "TBD", "fields": [ { "field": "encdec_vxmcfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXMC_VMADC => unsigned(vs2_val[i]) + unsigned(rs1_val) > 2 ^ SEW - 1,\n VXMC_VMSBC => unsigned(vs2_val[i]) - unsigned(rs1_val) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadc.vxm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vxmfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXM_VMADC => unsigned(vs2_val[i]) + unsigned(rs1_val) + unsigned(bool_to_bits(vm_val[i])) > 2 ^ SEW - 1,\n VXM_VMSBC => unsigned(vs2_val[i]) - unsigned(rs1_val) - unsigned(bool_to_bits(vm_val[i])) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VMACC => get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0) + vd_val[i],\n MVV_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0),\n MVV_VMADD => get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0) + vs2_val[i],\n MVV_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmadd.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvxmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VMACC => get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0) + vd_val[i],\n MVX_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0),\n MVX_VMADD => get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0) + vs2_val[i],\n MVX_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmand.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmandnot.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmax.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmax.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmaxu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmaxu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmerge.vim", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simm,v0", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let end_element = get_end_element();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW); /* max(VLMAX,VLEN/SEW)) */\n let real_num_elem = if LMUL_pow >= 0 then num_elem else num_elem / (0 - LMUL_pow); /* VLMAX */\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n let tail_ag : agtype = get_vtype_vta();\n foreach (i from 0 to (num_elem - 1)) {\n if i < start_element then {\n result[i] = vd_val[i]\n } else if i > end_element | i >= real_num_elem then {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n } else {\n /* the merge operates on all body elements */\n result[i] = if vm_val[i] then imm_val else vs2_val[i]\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmerge.vvm", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1,v0", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let end_element = get_end_element();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW); /* max(VLMAX,VLEN/SEW)) */\n let real_num_elem = if LMUL_pow >= 0 then num_elem else num_elem / (0 - LMUL_pow); /* VLMAX */\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n let tail_ag : agtype = get_vtype_vta();\n foreach (i from 0 to (num_elem - 1)) {\n if i < start_element then {\n result[i] = vd_val[i]\n } else if i > end_element | i >= real_num_elem then {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n } else {\n /* the merge operates on all body elements */\n result[i] = if vm_val[i] then vs1_val[i] else vs2_val[i]\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmerge.vxm", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1,v0", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let end_element = get_end_element();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW); /* max(VLMAX,VLEN/SEW)) */\n let real_num_elem = if LMUL_pow >= 0 then num_elem else num_elem / (0 - LMUL_pow); /* VLMAX */\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n let tail_ag : agtype = get_vtype_vta();\n foreach (i from 0 to (num_elem - 1)) {\n if i < start_element then {\n result[i] = vd_val[i]\n } else if i > end_element | i >= real_num_elem then {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n } else {\n /* the merge operates on all body elements */\n result[i] = if vm_val[i] then rs1_val else vs2_val[i]\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfeq.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VFM_VMFEQ => fp_eq(vs2_val[i], rs1_val),\n VFM_VMFNE => ~(fp_eq(vs2_val[i], rs1_val)),\n VFM_VMFLE => fp_le(vs2_val[i], rs1_val),\n VFM_VMFLT => fp_lt(vs2_val[i], rs1_val),\n VFM_VMFGE => fp_ge(vs2_val[i], rs1_val),\n VFM_VMFGT => fp_gt(vs2_val[i], rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfeq.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n FVVM_VMFEQ => fp_eq(vs2_val[i], vs1_val[i]),\n FVVM_VMFNE => ~(fp_eq(vs2_val[i], vs1_val[i])),\n FVVM_VMFLE => fp_le(vs2_val[i], vs1_val[i]),\n FVVM_VMFLT => fp_lt(vs2_val[i], vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfge.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VFM_VMFEQ => fp_eq(vs2_val[i], rs1_val),\n VFM_VMFNE => ~(fp_eq(vs2_val[i], rs1_val)),\n VFM_VMFLE => fp_le(vs2_val[i], rs1_val),\n VFM_VMFLT => fp_lt(vs2_val[i], rs1_val),\n VFM_VMFGE => fp_ge(vs2_val[i], rs1_val),\n VFM_VMFGT => fp_gt(vs2_val[i], rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfgt.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VFM_VMFEQ => fp_eq(vs2_val[i], rs1_val),\n VFM_VMFNE => ~(fp_eq(vs2_val[i], rs1_val)),\n VFM_VMFLE => fp_le(vs2_val[i], rs1_val),\n VFM_VMFLT => fp_lt(vs2_val[i], rs1_val),\n VFM_VMFGE => fp_ge(vs2_val[i], rs1_val),\n VFM_VMFGT => fp_gt(vs2_val[i], rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfle.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VFM_VMFEQ => fp_eq(vs2_val[i], rs1_val),\n VFM_VMFNE => ~(fp_eq(vs2_val[i], rs1_val)),\n VFM_VMFLE => fp_le(vs2_val[i], rs1_val),\n VFM_VMFLT => fp_lt(vs2_val[i], rs1_val),\n VFM_VMFGE => fp_ge(vs2_val[i], rs1_val),\n VFM_VMFGT => fp_gt(vs2_val[i], rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfle.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n FVVM_VMFEQ => fp_eq(vs2_val[i], vs1_val[i]),\n FVVM_VMFNE => ~(fp_eq(vs2_val[i], vs1_val[i])),\n FVVM_VMFLE => fp_le(vs2_val[i], vs1_val[i]),\n FVVM_VMFLT => fp_lt(vs2_val[i], vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmflt.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VFM_VMFEQ => fp_eq(vs2_val[i], rs1_val),\n VFM_VMFNE => ~(fp_eq(vs2_val[i], rs1_val)),\n VFM_VMFLE => fp_le(vs2_val[i], rs1_val),\n VFM_VMFLT => fp_lt(vs2_val[i], rs1_val),\n VFM_VMFGE => fp_ge(vs2_val[i], rs1_val),\n VFM_VMFGT => fp_gt(vs2_val[i], rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmflt.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n FVVM_VMFEQ => fp_eq(vs2_val[i], vs1_val[i]),\n FVVM_VMFNE => ~(fp_eq(vs2_val[i], vs1_val[i])),\n FVVM_VMFLE => fp_le(vs2_val[i], vs1_val[i]),\n FVVM_VMFLT => fp_lt(vs2_val[i], vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfne.vf", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvfmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvfmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar_fp(rs1, 'm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VFM_VMFEQ => fp_eq(vs2_val[i], rs1_val),\n VFM_VMFNE => ~(fp_eq(vs2_val[i], rs1_val)),\n VFM_VMFLE => fp_le(vs2_val[i], rs1_val),\n VFM_VMFLT => fp_lt(vs2_val[i], rs1_val),\n VFM_VMFGE => fp_ge(vs2_val[i], rs1_val),\n VFM_VMFGT => fp_gt(vs2_val[i], rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmfne.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "fvvmfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_fvvmfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let rm_3b = fcsr.FRM();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_fp_vd_unmasked(SEW, rm_3b) then { handle_illegal(); return RETIRE_FAIL };\n assert(SEW != 8);\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n FVVM_VMFEQ => fp_eq(vs2_val[i], vs1_val[i]),\n FVVM_VMFNE => ~(fp_eq(vs2_val[i], vs1_val[i])),\n FVVM_VMFLE => fp_le(vs2_val[i], vs1_val[i]),\n FVVM_VMFLT => fp_lt(vs2_val[i], vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmin.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmin.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vminu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vminu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmnand.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmnor.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmor.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmornot.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsbc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvmcfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_vvmcfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVMC_VMADC => unsigned(vs2_val[i]) + unsigned(vs1_val[i]) > 2 ^ SEW - 1,\n VVMC_VMSBC => unsigned(vs2_val[i]) - unsigned(vs1_val[i]) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsbc.vvm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vvmfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVM_VMADC => unsigned(vs2_val[i]) + unsigned(vs1_val[i]) + unsigned(bool_to_bits(vm_val[i])) > 2 ^ SEW - 1,\n VVM_VMSBC => unsigned(vs2_val[i]) - unsigned(vs1_val[i]) - unsigned(bool_to_bits(vm_val[i])) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsbc.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxmcfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1", "format": "TBD", "fields": [ { "field": "encdec_vxmcfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXMC_VMADC => unsigned(vs2_val[i]) + unsigned(rs1_val) > 2 ^ SEW - 1,\n VXMC_VMSBC => unsigned(vs2_val[i]) - unsigned(rs1_val) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsbc.vxm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vxmfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, LMUL_pow, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXM_VMADC => unsigned(vs2_val[i]) + unsigned(rs1_val) + unsigned(bool_to_bits(vm_val[i])) > 2 ^ SEW - 1,\n VXM_VMSBC => unsigned(vs2_val[i]) - unsigned(rs1_val) - unsigned(bool_to_bits(vm_val[i])) < 0\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsbf.m", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010100", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b00001", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_normal(vd, vm) | not(assert_vstart(0)) | vd == vs2\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, 0, vd_val, vm_val);\n\n found_elem : bool = false;\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n if vs2_val[i] then found_elem = true;\n result[i] = if found_elem then false else true\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmseq.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vicmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vicmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VICMP_VMSEQ => vs2_val[i] == imm_val,\n VICMP_VMSNE => vs2_val[i] != imm_val,\n VICMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(imm_val),\n VICMP_VMSLE => signed(vs2_val[i]) <= signed(imm_val),\n VICMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(imm_val),\n VICMP_VMSGT => signed(vs2_val[i]) > signed(imm_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmseq.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVCMP_VMSEQ => vs2_val[i] == vs1_val[i],\n VVCMP_VMSNE => vs2_val[i] != vs1_val[i],\n VVCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(vs1_val[i]),\n VVCMP_VMSLT => signed(vs2_val[i]) < signed(vs1_val[i]),\n VVCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(vs1_val[i]),\n VVCMP_VMSLE => signed(vs2_val[i]) <= signed(vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmseq.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsgt.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vicmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vicmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VICMP_VMSEQ => vs2_val[i] == imm_val,\n VICMP_VMSNE => vs2_val[i] != imm_val,\n VICMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(imm_val),\n VICMP_VMSLE => signed(vs2_val[i]) <= signed(imm_val),\n VICMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(imm_val),\n VICMP_VMSGT => signed(vs2_val[i]) > signed(imm_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsgt.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsgtu.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vicmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vicmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VICMP_VMSEQ => vs2_val[i] == imm_val,\n VICMP_VMSNE => vs2_val[i] != imm_val,\n VICMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(imm_val),\n VICMP_VMSLE => signed(vs2_val[i]) <= signed(imm_val),\n VICMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(imm_val),\n VICMP_VMSGT => signed(vs2_val[i]) > signed(imm_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsgtu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsif.m", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010100", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b00011", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_normal(vd, vm) | not(assert_vstart(0)) | vd == vs2\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, 0, vd_val, vm_val);\n\n found_elem : bool = false;\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = if found_elem then false else true;\n if vs2_val[i] then found_elem = true\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsle.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vicmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vicmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VICMP_VMSEQ => vs2_val[i] == imm_val,\n VICMP_VMSNE => vs2_val[i] != imm_val,\n VICMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(imm_val),\n VICMP_VMSLE => signed(vs2_val[i]) <= signed(imm_val),\n VICMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(imm_val),\n VICMP_VMSGT => signed(vs2_val[i]) > signed(imm_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsle.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVCMP_VMSEQ => vs2_val[i] == vs1_val[i],\n VVCMP_VMSNE => vs2_val[i] != vs1_val[i],\n VVCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(vs1_val[i]),\n VVCMP_VMSLT => signed(vs2_val[i]) < signed(vs1_val[i]),\n VVCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(vs1_val[i]),\n VVCMP_VMSLE => signed(vs2_val[i]) <= signed(vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsle.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsleu.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vicmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vicmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VICMP_VMSEQ => vs2_val[i] == imm_val,\n VICMP_VMSNE => vs2_val[i] != imm_val,\n VICMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(imm_val),\n VICMP_VMSLE => signed(vs2_val[i]) <= signed(imm_val),\n VICMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(imm_val),\n VICMP_VMSGT => signed(vs2_val[i]) > signed(imm_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsleu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVCMP_VMSEQ => vs2_val[i] == vs1_val[i],\n VVCMP_VMSNE => vs2_val[i] != vs1_val[i],\n VVCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(vs1_val[i]),\n VVCMP_VMSLT => signed(vs2_val[i]) < signed(vs1_val[i]),\n VVCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(vs1_val[i]),\n VVCMP_VMSLE => signed(vs2_val[i]) <= signed(vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsleu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmslt.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVCMP_VMSEQ => vs2_val[i] == vs1_val[i],\n VVCMP_VMSNE => vs2_val[i] != vs1_val[i],\n VVCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(vs1_val[i]),\n VVCMP_VMSLT => signed(vs2_val[i]) < signed(vs1_val[i]),\n VVCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(vs1_val[i]),\n VVCMP_VMSLE => signed(vs2_val[i]) <= signed(vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmslt.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsltu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVCMP_VMSEQ => vs2_val[i] == vs1_val[i],\n VVCMP_VMSNE => vs2_val[i] != vs1_val[i],\n VVCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(vs1_val[i]),\n VVCMP_VMSLT => signed(vs2_val[i]) < signed(vs1_val[i]),\n VVCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(vs1_val[i]),\n VVCMP_VMSLE => signed(vs2_val[i]) <= signed(vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsltu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsne.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vicmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vicmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VICMP_VMSEQ => vs2_val[i] == imm_val,\n VICMP_VMSNE => vs2_val[i] != imm_val,\n VICMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(imm_val),\n VICMP_VMSLE => signed(vs2_val[i]) <= signed(imm_val),\n VICMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(imm_val),\n VICMP_VMSGT => signed(vs2_val[i]) > signed(imm_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsne.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VVCMP_VMSEQ => vs2_val[i] == vs1_val[i],\n VVCMP_VMSNE => vs2_val[i] != vs1_val[i],\n VVCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(vs1_val[i]),\n VVCMP_VMSLT => signed(vs2_val[i]) < signed(vs1_val[i]),\n VVCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(vs1_val[i]),\n VVCMP_VMSLE => signed(vs2_val[i]) <= signed(vs1_val[i])\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsne.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxcmpfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxcmpfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let res : bool = match funct6 {\n VXCMP_VMSEQ => vs2_val[i] == rs1_val,\n VXCMP_VMSNE => vs2_val[i] != rs1_val,\n VXCMP_VMSLTU => unsigned(vs2_val[i]) < unsigned(rs1_val),\n VXCMP_VMSLT => signed(vs2_val[i]) < signed(rs1_val),\n VXCMP_VMSLEU => unsigned(vs2_val[i]) <= unsigned(rs1_val),\n VXCMP_VMSLE => signed(vs2_val[i]) <= signed(rs1_val),\n VXCMP_VMSGTU => unsigned(vs2_val[i]) > unsigned(rs1_val),\n VXCMP_VMSGT => signed(vs2_val[i]) > signed(rs1_val)\n };\n result[i] = res\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmsof.m", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010100", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b00010", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_normal(vd, vm) | not(assert_vstart(0)) | vd == vs2\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, 0, vd_val, vm_val);\n\n found_elem : bool = false;\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n if vs2_val[i] & not(found_elem) then {\n result[i] = true;\n found_elem = true\n } else {\n result[i] = false\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmul.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmul.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmulh.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmulh.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmulhsu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmulhsu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmulhu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmulhu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv.s.x", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let num_elem = get_num_elem(0, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n assert(num_elem > 0);\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, 'm);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, 0, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, 0, vd_val, vm_val);\n\n /* one body element */\n if mask[0] then result[0] = rs1_val;\n\n /* others treated as tail elements */\n let tail_ag : agtype = get_vtype_vta();\n foreach (i from 1 to (num_elem - 1)) {\n result[i] = match tail_ag {\n UNDISTURBED => vd_val[i],\n AGNOSTIC => vd_val[i] /* TODO: configuration support */\n }\n };\n\n write_vreg(num_elem, SEW, 0, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv.v.i", "name": "TBD", "operands": [ { "name": "vd", "type": "regidx" }, { "name": "simm", "type": "bits(5)" } ], "syntax": "vd,simm", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then result[i] = imm_val\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv.v.v", "name": "TBD", "operands": [ { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then result[i] = vs1_val[i]\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv.v.x", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1", "format": "TBD", "fields": [ { "field": "0b010111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let rs1_val : bits('m) = get_scalar(rs1, 'm);\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then result[i] = rs1_val\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv.x.s", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,vs2", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b00000", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let num_elem = get_num_elem(0, SEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n assert(num_elem > 0);\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, 0, vs2);\n X(rd) = if sizeof(xlen) < SEW then slice(vs2_val[0], 0, sizeof(xlen))\n else if sizeof(xlen) > SEW then sign_extend(vs2_val[0])\n else vs2_val[0];\n vstart = zeros();\n\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv1r.v", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2", "format": "TBD", "fields": [ { "field": "0b100111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let SEW = get_sew();\n let imm_val = unsigned(zero_extend(sizeof(xlen), simm));\n let EMUL = imm_val + 1;\n\n if not(EMUL == 1 | EMUL == 2 | EMUL == 4 | EMUL == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n let EMUL_pow = log2(EMUL);\n let num_elem = get_num_elem(EMUL_pow, SEW);\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n foreach (i from 0 to (num_elem - 1)) {\n result[i] = if i < start_element then vd_val[i] else vs2_val[i]\n };\n\n write_vreg(num_elem, SEW, EMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv2r.v", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2", "format": "TBD", "fields": [ { "field": "0b100111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let SEW = get_sew();\n let imm_val = unsigned(zero_extend(sizeof(xlen), simm));\n let EMUL = imm_val + 1;\n\n if not(EMUL == 1 | EMUL == 2 | EMUL == 4 | EMUL == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n let EMUL_pow = log2(EMUL);\n let num_elem = get_num_elem(EMUL_pow, SEW);\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n foreach (i from 0 to (num_elem - 1)) {\n result[i] = if i < start_element then vd_val[i] else vs2_val[i]\n };\n\n write_vreg(num_elem, SEW, EMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv4r.v", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2", "format": "TBD", "fields": [ { "field": "0b100111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let SEW = get_sew();\n let imm_val = unsigned(zero_extend(sizeof(xlen), simm));\n let EMUL = imm_val + 1;\n\n if not(EMUL == 1 | EMUL == 2 | EMUL == 4 | EMUL == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n let EMUL_pow = log2(EMUL);\n let num_elem = get_num_elem(EMUL_pow, SEW);\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n foreach (i from 0 to (num_elem - 1)) {\n result[i] = if i < start_element then vd_val[i] else vs2_val[i]\n };\n\n write_vreg(num_elem, SEW, EMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmv8r.v", "name": "TBD", "operands": [ { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2", "format": "TBD", "fields": [ { "field": "0b100111", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let start_element = get_start_element();\n let SEW = get_sew();\n let imm_val = unsigned(zero_extend(sizeof(xlen), simm));\n let EMUL = imm_val + 1;\n\n if not(EMUL == 1 | EMUL == 2 | EMUL == 4 | EMUL == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n let EMUL_pow = log2(EMUL);\n let num_elem = get_num_elem(EMUL_pow, SEW);\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, 0b00000);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, EMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n\n foreach (i from 0 to (num_elem - 1)) {\n result[i] = if i < start_element then vd_val[i] else vs2_val[i]\n };\n\n write_vreg(num_elem, SEW, EMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmxnor.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vmxor.mm", "name": "TBD", "operands": [ { "name": "funct6", "type": "mmfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1", "format": "TBD", "fields": [ { "field": "encdec_mmfunct6(funct6)", "size": 6 }, { "field": "0b1", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vs1_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs1);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n let vd_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vd);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_carry(num_elem, SEW, 0, vd_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MM_VMAND => vs2_val[i] & vs1_val[i],\n MM_VMNAND => not(vs2_val[i] & vs1_val[i]),\n MM_VMANDNOT => vs2_val[i] & not(vs1_val[i]),\n MM_VMXOR => vs2_val[i] != vs1_val[i],\n MM_VMOR => vs2_val[i] | vs1_val[i],\n MM_VMNOR => not(vs2_val[i] | vs1_val[i]),\n MM_VMORNOT => vs2_val[i] | not(vs1_val[i]),\n MM_VMXNOR => vs2_val[i] == vs1_val[i]\n }\n }\n };\n\n write_vmask(num_elem, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnclip.wi", "name": "TBD", "operands": [ { "name": "funct6", "type": "nifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_nifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let shift_amount = get_shift_amount(imm_val, SEW_widen);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n result[i] = match funct6 {\n NI_VNCLIPU => {\n let result_wide = (vs2_val[i] >> shift_amount) + zero_extend('o, rounding_incr);\n unsigned_saturation('m, result_wide)\n },\n NI_VNCLIP => {\n let v_double : bits('m * 4) = sign_extend(vs2_val[i]);\n let result_wide = slice(v_double >> shift_amount, 0, 'o) + zero_extend('o, rounding_incr);\n signed_saturation('m, result_wide)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnclip.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "nvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_nvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let shift_amount = get_shift_amount(vs1_val[i], SEW_widen);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n result[i] = match funct6 {\n NV_VNCLIPU => {\n let result_wide = (vs2_val[i] >> shift_amount) + zero_extend('o, rounding_incr);\n unsigned_saturation('m, result_wide);\n },\n NV_VNCLIP => {\n let v_double : bits('m * 4) = sign_extend(vs2_val[i]);\n let result_wide = slice(v_double >> shift_amount, 0, 'o) + zero_extend('o, rounding_incr);\n signed_saturation('m, result_wide);\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnclip.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "nxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_nxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let shift_amount = get_shift_amount(rs1_val, SEW_widen);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n result[i] = match funct6 {\n NX_VNCLIPU => {\n let result_wide = (vs2_val[i] >> shift_amount) + zero_extend('o, rounding_incr);\n unsigned_saturation('m, result_wide)\n },\n NX_VNCLIP => {\n let v_double : bits('m * 4) = sign_extend(vs2_val[i]);\n let result_wide = slice(v_double >> shift_amount, 0, 'o) + zero_extend('o, rounding_incr);\n signed_saturation('m, result_wide)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnclipu.wi", "name": "TBD", "operands": [ { "name": "funct6", "type": "nifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_nifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let shift_amount = get_shift_amount(imm_val, SEW_widen);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n result[i] = match funct6 {\n NI_VNCLIPU => {\n let result_wide = (vs2_val[i] >> shift_amount) + zero_extend('o, rounding_incr);\n unsigned_saturation('m, result_wide)\n },\n NI_VNCLIP => {\n let v_double : bits('m * 4) = sign_extend(vs2_val[i]);\n let result_wide = slice(v_double >> shift_amount, 0, 'o) + zero_extend('o, rounding_incr);\n signed_saturation('m, result_wide)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnclipu.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "nvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_nvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let shift_amount = get_shift_amount(vs1_val[i], SEW_widen);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n result[i] = match funct6 {\n NV_VNCLIPU => {\n let result_wide = (vs2_val[i] >> shift_amount) + zero_extend('o, rounding_incr);\n unsigned_saturation('m, result_wide);\n },\n NV_VNCLIP => {\n let v_double : bits('m * 4) = sign_extend(vs2_val[i]);\n let result_wide = slice(v_double >> shift_amount, 0, 'o) + zero_extend('o, rounding_incr);\n signed_saturation('m, result_wide);\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnclipu.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "nxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_nxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n let shift_amount = get_shift_amount(rs1_val, SEW_widen);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n result[i] = match funct6 {\n NX_VNCLIPU => {\n let result_wide = (vs2_val[i] >> shift_amount) + zero_extend('o, rounding_incr);\n unsigned_saturation('m, result_wide)\n },\n NX_VNCLIP => {\n let v_double : bits('m * 4) = sign_extend(vs2_val[i]);\n let result_wide = slice(v_double >> shift_amount, 0, 'o) + zero_extend('o, rounding_incr);\n signed_saturation('m, result_wide)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnmsac.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VMACC => get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0) + vd_val[i],\n MVV_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0),\n MVV_VMADD => get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0) + vs2_val[i],\n MVV_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnmsac.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvxmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VMACC => get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0) + vd_val[i],\n MVX_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0),\n MVX_VMADD => get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0) + vs2_val[i],\n MVX_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnmsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvvmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VMACC => get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0) + vd_val[i],\n MVV_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vs2_val[i]), 0),\n MVV_VMADD => get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0) + vs2_val[i],\n MVV_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(vs1_val[i]) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnmsub.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxmafunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_mvxmafunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VMACC => get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0) + vd_val[i],\n MVX_VNMSAC => vd_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vs2_val[i]), 0),\n MVX_VMADD => get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0) + vs2_val[i],\n MVX_VNMSUB => vs2_val[i] - get_slice_int(SEW, signed(rs1_val) * signed(vd_val[i]), 0)\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnsra.wi", "name": "TBD", "operands": [ { "name": "funct6", "type": "nisfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_nisfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n NIS_VNSRL => {\n let shift_amount = get_shift_amount(imm_val, SEW_widen);\n slice(vs2_val[i] >> shift_amount, 0, SEW)\n },\n NIS_VNSRA => {\n let shift_amount = get_shift_amount(imm_val, SEW_widen);\n let v_double : bits('o * 2) = sign_extend(vs2_val[i]);\n let arith_shifted : bits('o) = slice(v_double >> shift_amount, 0, SEW_widen);\n slice(arith_shifted, 0, SEW)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnsra.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "nvsfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_nvsfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n NVS_VNSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW_widen);\n slice(vs2_val[i] >> shift_amount, 0, SEW)\n },\n NVS_VNSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW_widen);\n let v_double : bits('o * 2) = sign_extend(vs2_val[i]);\n let arith_shifted : bits('o) = slice(v_double >> shift_amount, 0, SEW_widen);\n slice(arith_shifted, 0, SEW)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnsra.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "nxsfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_nxsfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n NXS_VNSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW_widen);\n slice(vs2_val[i] >> shift_amount, 0, SEW)\n },\n NXS_VNSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW_widen);\n let v_double : bits('o * 2) = sign_extend(vs2_val[i]);\n let arith_shifted : bits('o) = slice(v_double >> shift_amount, 0, SEW_widen);\n slice(arith_shifted, 0, SEW)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnsrl.wi", "name": "TBD", "operands": [ { "name": "funct6", "type": "nisfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_nisfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n NIS_VNSRL => {\n let shift_amount = get_shift_amount(imm_val, SEW_widen);\n slice(vs2_val[i] >> shift_amount, 0, SEW)\n },\n NIS_VNSRA => {\n let shift_amount = get_shift_amount(imm_val, SEW_widen);\n let v_double : bits('o * 2) = sign_extend(vs2_val[i]);\n let arith_shifted : bits('o) = slice(v_double >> shift_amount, 0, SEW_widen);\n slice(arith_shifted, 0, SEW)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnsrl.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "nvsfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_nvsfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n NVS_VNSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW_widen);\n slice(vs2_val[i] >> shift_amount, 0, SEW)\n },\n NVS_VNSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW_widen);\n let v_double : bits('o * 2) = sign_extend(vs2_val[i]);\n let arith_shifted : bits('o) = slice(v_double >> shift_amount, 0, SEW_widen);\n slice(arith_shifted, 0, SEW)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vnsrl.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "nxsfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_nxsfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_widen, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW_widen <= 64);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n NXS_VNSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW_widen);\n slice(vs2_val[i] >> shift_amount, 0, SEW)\n },\n NXS_VNSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW_widen);\n let v_double : bits('o * 2) = sign_extend(vs2_val[i]);\n let arith_shifted : bits('o) = slice(v_double >> shift_amount, 0, SEW_widen);\n slice(arith_shifted, 0, SEW)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vor.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vor.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vor.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vpopc.m", "name": "TBD", "operands": [ { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010000", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "0b10000", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = unsigned(vlenb) * 8;\n\n if illegal_vd_unmasked() | not(assert_vstart(0)) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs2_val : vector('n, dec, bool) = read_vmask(num_elem, 0b0, vs2);\n result : vector('n, dec, bool) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result_cmp(num_elem, SEW, 0, vs2_val, vm_val);\n\n count : nat = 0;\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] & vs2_val[i] then count = count + 1;\n };\n\n X(rd) = to_bits(sizeof(xlen), count);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredand.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredmax.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredmaxu.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredmin.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredminu.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredor.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredsum.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vredxor.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW); /* vd regardless of LMUL setting */\n\n if illegal_reduction() then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('m)) = read_vreg(num_elem_vd, SEW, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('m) = read_single_element(SEW, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n sum = match funct6 {\n MVV_VREDSUM => sum + vs2_val[i],\n MVV_VREDAND => sum & vs2_val[i],\n MVV_VREDOR => sum | vs2_val[i],\n MVV_VREDXOR => sum ^ vs2_val[i],\n MVV_VREDMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(sum))),\n MVV_VREDMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(sum))),\n MVV_VREDMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(sum)))\n }\n }\n };\n\n write_single_element(SEW, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrem.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrem.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vremu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVV_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i]);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVV_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), 0),\n MVV_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(vs1_val[i]), SEW),\n MVV_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(vs1_val[i]), SEW),\n MVV_VDIVU => {\n let q : int = if unsigned(vs1_val[i]) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n to_bits(SEW, q)\n },\n MVV_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(vs1_val[i]) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVV_VREMU => {\n let r : int = if unsigned(vs1_val[i]) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVV_VREM => {\n let r : int = if signed(vs1_val[i]) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(vs1_val[i]));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vremu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrgather.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "visgfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_visgfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : nat = unsigned(zero_extend(sizeof(xlen), simm));\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VSLIDEUP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i >= imm_val then vs2_val[i - imm_val] else vd_val[i]\n },\n VI_VSLIDEDOWN => {\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if i + imm_val < VLMAX then vs2_val[i + imm_val] else zeros()\n },\n VI_VRGATHER => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if imm_val < VLMAX then vs2_val[imm_val] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrgather.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrgather.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxsgfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxsgfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : nat = unsigned(X(rs1));\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VSLIDEUP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i >= rs1_val then vs2_val[i - rs1_val] else vd_val[i]\n },\n VX_VSLIDEDOWN => {\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if i + rs1_val < VLMAX then vs2_val[i + rs1_val] else zeros()\n },\n VX_VRGATHER => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if rs1_val < VLMAX then vs2_val[rs1_val] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrgatherei16.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrsub.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vrsub.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsadd.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsadd.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsaddu.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsaddu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsaddu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsbc.vvm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvmsfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vvmsfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n /* for bypassing normal masking in init_masked_result */\n vec_trues : vector('n, dec, bool) = undefined;\n foreach (i from 0 to (num_elem - 1)) {\n vec_trues[i] = true\n };\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vec_trues);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VVMS_VADC => to_bits(SEW, unsigned(vs2_val[i]) + unsigned(vs1_val[i]) + unsigned(bool_to_bits(vm_val[i]))),\n VVMS_VSBC => to_bits(SEW, unsigned(vs2_val[i]) - unsigned(vs1_val[i]) - unsigned(bool_to_bits(vm_val[i])))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsbc.vxm", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxmsfunct6" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1,v0", "format": "TBD", "fields": [ { "field": "encdec_vxmsfunct6(funct6)", "size": 6 }, { "field": "0b0", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_vd_masked(vd) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n /* for bypassing normal masking in init_masked_result */\n vec_trues : vector('n, dec, bool) = undefined;\n foreach (i from 0 to (num_elem - 1)) {\n vec_trues[i] = true\n };\n\n let vm_val : vector('n, dec, bool) = read_vmask_carry(num_elem, 0b0, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vec_trues);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VXMS_VADC => to_bits(SEW, unsigned(vs2_val[i]) + unsigned(rs1_val) + unsigned(bool_to_bits(vm_val[i]))),\n VXMS_VSBC => to_bits(SEW, unsigned(vs2_val[i]) - unsigned(rs1_val) - unsigned(bool_to_bits(vm_val[i])))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vse16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vse32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vse64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vse8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsetivli", "name": "TBD", "operands": [ { "name": "ma", "type": "bits(1)" }, { "name": "ta", "type": "bits(1)" }, { "name": "sew", "type": "bits(3)" }, { "name": "lmul", "type": "bits(3)" }, { "name": "uimm", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,uimm,sew_flag(sew)maybe_lmul_flag(lmul)maybe_ta_flag(ta)maybe_ma_flag(ma)", "format": "TBD", "fields": [ { "field": "0b1100", "size": 4 }, { "field": "ma", "size": 1 }, { "field": "ta", "size": 1 }, { "field": "sew", "size": 3 }, { "field": "lmul", "size": 3 }, { "field": "uimm", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let VLEN_pow = get_vlen_pow();\n let ELEN_pow = get_elen_pow();\n let LMUL_pow_ori = get_lmul_pow();\n let SEW_pow_ori = get_sew_pow();\n let ratio_pow_ori = SEW_pow_ori - LMUL_pow_ori;\n\n /* set vtype */\n vtype->bits() = 0b0 @ zeros(sizeof(xlen) - 9) @ ma @ ta @ sew @ lmul;\n\n /* check legal SEW and LMUL and calculate VLMAX */\n let LMUL_pow_new = get_lmul_pow();\n let SEW_pow_new = get_sew_pow();\n if SEW_pow_new > LMUL_pow_new + ELEN_pow then {\n /* Note: Implementations can set vill or trap if the vtype setting is not supported.\n * TODO: configuration support for both solutions\n */\n vtype->bits() = 0b1 @ zeros(sizeof(xlen) - 1); /* set vtype.vill */\n vl = zeros();\n print_reg(\"CSR vtype <- \" ^ BitStr(vtype.bits()));\n print_reg(\"CSR vl <- \" ^ BitStr(vl));\n return RETIRE_SUCCESS\n };\n let VLMAX = int_power(2, VLEN_pow + LMUL_pow_new - SEW_pow_new);\n let AVL = unsigned(uimm); /* AVL is encoded as 5-bit zero-extended imm in the rs1 field */\n\n /* set vl according to VLMAX and AVL */\n vl = if AVL <= VLMAX then to_bits(sizeof(xlen), AVL)\n else if AVL < 2 * VLMAX then to_bits(sizeof(xlen), (AVL + 1) / 2)\n else to_bits(sizeof(xlen), VLMAX);\n /* Note: ceil(AVL / 2) <= vl <= VLMAX when VLMAX < AVL < (2 * VLMAX)\n * TODO: configuration support for either using ceil(AVL / 2) or VLMAX\n */\n X(rd) = vl;\n print_reg(\"CSR vtype <- \" ^ BitStr(vtype.bits()));\n print_reg(\"CSR vl <- \" ^ BitStr(vl));\n\n /* reset vstart to 0 */\n vstart = zeros();\n print_reg(\"CSR vstart <- \" ^ BitStr(vstart));\n\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsetvli", "name": "TBD", "operands": [ { "name": "op", "type": "vsetop" }, { "name": "ma", "type": "bits(1)" }, { "name": "ta", "type": "bits(1)" }, { "name": "sew", "type": "bits(3)" }, { "name": "lmul", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,sew_flag(sew)maybe_lmul_flag(lmul)maybe_ta_flag(ta)maybe_ma_flag(ma)", "format": "TBD", "fields": [ { "field": "encdec_vsetop(op)", "size": 4 }, { "field": "ma", "size": 1 }, { "field": "ta", "size": 1 }, { "field": "sew", "size": 3 }, { "field": "lmul", "size": 3 }, { "field": "rs1", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let VLEN_pow = get_vlen_pow();\n let ELEN_pow = get_elen_pow();\n let LMUL_pow_ori = get_lmul_pow();\n let SEW_pow_ori = get_sew_pow();\n let ratio_pow_ori = SEW_pow_ori - LMUL_pow_ori;\n\n /* set vtype */\n match op {\n VSETVLI => {\n vtype->bits() = 0b0 @ zeros(sizeof(xlen) - 9) @ ma @ ta @ sew @ lmul\n },\n VSETVL => {\n let rs2 : regidx = sew[1 .. 0] @ lmul;\n vtype->bits() = X(rs2)\n }\n };\n\n /* check legal SEW and LMUL and calculate VLMAX */\n let LMUL_pow_new = get_lmul_pow();\n let SEW_pow_new = get_sew_pow();\n if SEW_pow_new > LMUL_pow_new + ELEN_pow then {\n /* Note: Implementations can set vill or trap if the vtype setting is not supported.\n * TODO: configuration support for both solutions\n */\n vtype->bits() = 0b1 @ zeros(sizeof(xlen) - 1); /* set vtype.vill */\n vl = zeros();\n print_reg(\"CSR vtype <- \" ^ BitStr(vtype.bits()));\n print_reg(\"CSR vl <- \" ^ BitStr(vl));\n return RETIRE_SUCCESS\n };\n let VLMAX = int_power(2, VLEN_pow + LMUL_pow_new - SEW_pow_new);\n\n /* set vl according to VLMAX and AVL */\n if (rs1 != 0b00000) then { /* normal stripmining */\n let rs1_val = X(rs1);\n let AVL = unsigned(rs1_val);\n vl = if AVL <= VLMAX then to_bits(sizeof(xlen), AVL)\n else if AVL < 2 * VLMAX then to_bits(sizeof(xlen), (AVL + 1) / 2)\n else to_bits(sizeof(xlen), VLMAX);\n /* Note: ceil(AVL / 2) <= vl <= VLMAX when VLMAX < AVL < (2 * VLMAX)\n * TODO: configuration support for either using ceil(AVL / 2) or VLMAX\n */\n X(rd) = vl;\n } else if (rd != 0b00000) then { /* set vl to VLMAX */\n let AVL = unsigned(ones(sizeof(xlen)));\n vl = to_bits(sizeof(xlen), VLMAX);\n X(rd) = vl;\n } else { /* keep existing vl */\n let AVL = unsigned(vl);\n let ratio_pow_new = SEW_pow_new - LMUL_pow_new;\n if (ratio_pow_new != ratio_pow_ori) then {\n /* Note: Implementations can set vill or trap if the vtype setting is not supported.\n * TODO: configuration support for both solutions\n */\n vtype->bits() = 0b1 @ zeros(sizeof(xlen) - 1); /* set vtype.vill */\n vl = zeros();\n }\n };\n print_reg(\"CSR vtype <- \" ^ BitStr(vtype.bits()));\n print_reg(\"CSR vl <- \" ^ BitStr(vl));\n\n /* reset vstart to 0 */\n vstart = zeros();\n print_reg(\"CSR vstart <- \" ^ BitStr(vstart));\n\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsetvli", "name": "TBD", "operands": [ { "name": "op", "type": "vsetop" }, { "name": "ma", "type": "bits(1)" }, { "name": "ta", "type": "bits(1)" }, { "name": "sew", "type": "bits(3)" }, { "name": "lmul", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,sew_flag(sew)maybe_lmul_flag(lmul)maybe_ta_flag(ta)maybe_ma_flag(ma)", "format": "TBD", "fields": [ { "field": "encdec_vsetop(op)", "size": 4 }, { "field": "ma", "size": 1 }, { "field": "ta", "size": 1 }, { "field": "sew", "size": 3 }, { "field": "lmul", "size": 3 }, { "field": "rs1", "size": 5 }, { "field": "0b111", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let VLEN_pow = get_vlen_pow();\n let ELEN_pow = get_elen_pow();\n let LMUL_pow_ori = get_lmul_pow();\n let SEW_pow_ori = get_sew_pow();\n let ratio_pow_ori = SEW_pow_ori - LMUL_pow_ori;\n\n /* set vtype */\n match op {\n VSETVLI => {\n vtype->bits() = 0b0 @ zeros(sizeof(xlen) - 9) @ ma @ ta @ sew @ lmul\n },\n VSETVL => {\n let rs2 : regidx = sew[1 .. 0] @ lmul;\n vtype->bits() = X(rs2)\n }\n };\n\n /* check legal SEW and LMUL and calculate VLMAX */\n let LMUL_pow_new = get_lmul_pow();\n let SEW_pow_new = get_sew_pow();\n if SEW_pow_new > LMUL_pow_new + ELEN_pow then {\n /* Note: Implementations can set vill or trap if the vtype setting is not supported.\n * TODO: configuration support for both solutions\n */\n vtype->bits() = 0b1 @ zeros(sizeof(xlen) - 1); /* set vtype.vill */\n vl = zeros();\n print_reg(\"CSR vtype <- \" ^ BitStr(vtype.bits()));\n print_reg(\"CSR vl <- \" ^ BitStr(vl));\n return RETIRE_SUCCESS\n };\n let VLMAX = int_power(2, VLEN_pow + LMUL_pow_new - SEW_pow_new);\n\n /* set vl according to VLMAX and AVL */\n if (rs1 != 0b00000) then { /* normal stripmining */\n let rs1_val = X(rs1);\n let AVL = unsigned(rs1_val);\n vl = if AVL <= VLMAX then to_bits(sizeof(xlen), AVL)\n else if AVL < 2 * VLMAX then to_bits(sizeof(xlen), (AVL + 1) / 2)\n else to_bits(sizeof(xlen), VLMAX);\n /* Note: ceil(AVL / 2) <= vl <= VLMAX when VLMAX < AVL < (2 * VLMAX)\n * TODO: configuration support for either using ceil(AVL / 2) or VLMAX\n */\n X(rd) = vl;\n } else if (rd != 0b00000) then { /* set vl to VLMAX */\n let AVL = unsigned(ones(sizeof(xlen)));\n vl = to_bits(sizeof(xlen), VLMAX);\n X(rd) = vl;\n } else { /* keep existing vl */\n let AVL = unsigned(vl);\n let ratio_pow_new = SEW_pow_new - LMUL_pow_new;\n if (ratio_pow_new != ratio_pow_ori) then {\n /* Note: Implementations can set vill or trap if the vtype setting is not supported.\n * TODO: configuration support for both solutions\n */\n vtype->bits() = 0b1 @ zeros(sizeof(xlen) - 1); /* set vtype.vill */\n vl = zeros();\n }\n };\n print_reg(\"CSR vtype <- \" ^ BitStr(vtype.bits()));\n print_reg(\"CSR vl <- \" ^ BitStr(vl));\n\n /* reset vstart to 0 */\n vstart = zeros();\n print_reg(\"CSR vstart <- \" ^ BitStr(vstart));\n\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsext.vf2", "name": "TBD", "operands": [ { "name": "funct6", "type": "vext2funct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vext2_vs1(funct6)", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_half = SEW / 2;\n let LMUL_pow_half = LMUL_pow - 1;\n\n if illegal_variable_width(vd, vm, SEW_half, LMUL_pow_half) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_half, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_half;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_half, LMUL_pow_half, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW > SEW_half);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VEXT2_ZVF2 => zero_extend(vs2_val[i]),\n VEXT2_SVF2 => sign_extend(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsext.vf4", "name": "TBD", "operands": [ { "name": "funct6", "type": "vext4funct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vext4_vs1(funct6)", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_quart = SEW / 4;\n let LMUL_pow_quart = LMUL_pow - 2;\n\n if illegal_variable_width(vd, vm, SEW_quart, LMUL_pow_quart) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_quart, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_quart;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_quart, LMUL_pow_quart, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW > SEW_quart);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VEXT4_ZVF4 => zero_extend(vs2_val[i]),\n VEXT4_SVF4 => sign_extend(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsext.vf8", "name": "TBD", "operands": [ { "name": "funct6", "type": "vext8funct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vext8_vs1(funct6)", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_eighth = SEW / 8;\n let LMUL_pow_eighth = LMUL_pow - 3;\n\n if illegal_variable_width(vd, vm, SEW_eighth, LMUL_pow_eighth) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_eighth, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_eighth;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_eighth, LMUL_pow_eighth, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW > SEW_eighth);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VEXT8_ZVF8 => zero_extend(vs2_val[i]),\n VEXT8_SVF8 => sign_extend(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vslide1down.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vslide1up.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "mvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_mvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n MVX_VAADDU => {\n let result_add = zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VAADD => {\n let result_add = sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_add, 1);\n slice(result_add >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUBU => {\n let result_sub = zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VASUB => {\n let result_sub = sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val);\n let rounding_incr = get_fixed_rounding_incr(result_sub, 1);\n slice(result_sub >> 1, 0, 'm) + zero_extend('m, rounding_incr)\n },\n MVX_VSLIDE1UP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i == 0 then rs1_val else vs2_val[i - 1]\n },\n MVX_VSLIDE1DOWN => {\n let last_elem = get_end_element();\n assert(last_elem < num_elem);\n if i < last_elem then vs2_val[i + 1] else rs1_val\n },\n MVX_VMUL => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), 0),\n MVX_VMULH => get_slice_int(SEW, signed(vs2_val[i]) * signed(rs1_val), SEW),\n MVX_VMULHU => get_slice_int(SEW, unsigned(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VMULHSU => get_slice_int(SEW, signed(vs2_val[i]) * unsigned(rs1_val), SEW),\n MVX_VDIVU => {\n let q : int = if unsigned(rs1_val) == 0 then -1 else quot_round_zero(unsigned(vs2_val[i]), unsigned(rs1_val));\n to_bits(SEW, q)\n },\n MVX_VDIV => {\n let elem_max : int = 2 ^ (SEW - 1) - 1;\n let elem_min : int = 0 - 2 ^ (SEW - 1);\n let q : int = if signed(rs1_val) == 0 then -1 else quot_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* check for signed overflow */\n let q' : int = if q > elem_max then elem_min else q;\n to_bits(SEW, q')\n },\n MVX_VREMU => {\n let r : int = if unsigned(rs1_val) == 0 then unsigned(vs2_val[i]) else rem_round_zero(unsigned(vs2_val[i]), unsigned (rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n },\n MVX_VREM => {\n let r : int = if signed(rs1_val) == 0 then signed(vs2_val[i]) else rem_round_zero(signed(vs2_val[i]), signed(rs1_val));\n /* signed overflow case returns zero naturally as required due to -1 divisor */\n to_bits(SEW, r)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vslidedown.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "visgfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_visgfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : nat = unsigned(zero_extend(sizeof(xlen), simm));\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VSLIDEUP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i >= imm_val then vs2_val[i - imm_val] else vd_val[i]\n },\n VI_VSLIDEDOWN => {\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if i + imm_val < VLMAX then vs2_val[i + imm_val] else zeros()\n },\n VI_VRGATHER => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if imm_val < VLMAX then vs2_val[imm_val] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vslidedown.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxsgfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxsgfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : nat = unsigned(X(rs1));\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VSLIDEUP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i >= rs1_val then vs2_val[i - rs1_val] else vd_val[i]\n },\n VX_VSLIDEDOWN => {\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if i + rs1_val < VLMAX then vs2_val[i + rs1_val] else zeros()\n },\n VX_VRGATHER => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if rs1_val < VLMAX then vs2_val[rs1_val] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vslideup.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "visgfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_visgfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : nat = unsigned(zero_extend(sizeof(xlen), simm));\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VSLIDEUP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i >= imm_val then vs2_val[i - imm_val] else vd_val[i]\n },\n VI_VSLIDEDOWN => {\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if i + imm_val < VLMAX then vs2_val[i + imm_val] else zeros()\n },\n VI_VRGATHER => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if imm_val < VLMAX then vs2_val[imm_val] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vslideup.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxsgfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxsgfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : nat = unsigned(X(rs1));\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VSLIDEUP => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n if i >= rs1_val then vs2_val[i - rs1_val] else vd_val[i]\n },\n VX_VSLIDEDOWN => {\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if i + rs1_val < VLMAX then vs2_val[i + rs1_val] else zeros()\n },\n VX_VRGATHER => {\n if (vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX > 0 & VLMAX <= 'n);\n if rs1_val < VLMAX then vs2_val[rs1_val] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsll.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsll.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsll.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsm.v", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "vd_or_vs3", "type": "regidx" }, { "name": "op", "type": "vmlsop" } ], "syntax": "vd_or_vs3,(rs1)", "format": "TBD", "fields": [ { "field": "0b000", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01011", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd_or_vs3", "size": 5 }, { "field": "encdec_lsop(op)", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW = 8;\n let EMUL_pow = 0;\n let vl_val = unsigned(vl);\n let evl : int = if vl_val % 8 == 0 then vl_val / 8 else vl_val / 8 + 1; /* the effective vector length is evl=ceil(vl/8) */\n let num_elem = get_num_elem(EMUL_pow, EEW);\n\n if illegal_vd_unmasked() then { handle_illegal(); return RETIRE_FAIL };\n\n assert(evl >= 0);\n process_vm(vd_or_vs3, rs1, num_elem, evl, op)\n}", "description": "TBD" }, { "mnemonic": "vsmul.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsmul.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsoxei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg2ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg2ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg2ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg2ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg3ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg3ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg3ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg3ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg4ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg4ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg4ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg4ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg5ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg5ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg5ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg5ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg6ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg6ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg6ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg6ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg7ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg7ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg7ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg7ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg8ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg8ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg8ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsoxseg8ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsr.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsra.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsra.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsra.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsrl.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsrl.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsrl.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsse16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsse32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsse64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsse8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg2e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg2e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg2e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg2e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg2r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsseg3e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg3e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg3e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg3e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg3r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsseg4e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg4e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg4e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg4e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg4r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsseg5e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg5e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg5e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg5e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg5r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsseg6e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg6e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg6e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg6e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg6r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsseg7e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg7e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg7e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg7e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg7r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vsseg8e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg8e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg8e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg8e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsseg(nf_int, vm, vs3, load_width_bytes, rs1, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vsseg8r.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "rs1", "type": "regidx" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1)", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b00", "size": 2 }, { "field": "0b1", "size": 1 }, { "field": "0b01000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = 1;\n let EEW = 8;\n let VLEN = unsigned(vlenb) * 8;\n let elem_per_reg : int = VLEN / EEW;\n let nf_int = nfields_int(nf);\n\n assert(elem_per_reg >= 0);\n if not(nf_int == 1 | nf_int == 2 | nf_int == 4 | nf_int == 8) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsre(nf_int, load_width_bytes, rs1, vs3, elem_per_reg)\n}", "description": "TBD" }, { "mnemonic": "vssra.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssra.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssra.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssrl.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssrl.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssrl.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssseg2e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg2e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg2e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg2e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg3e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg3e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg3e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg3e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg4e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg4e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg4e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg4e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg5e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg5e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg5e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg5e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg6e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg6e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg6e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg6e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg7e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg7e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg7e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg7e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg8e16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg8e32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg8e64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssseg8e8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),rs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b10", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let load_width_bytes = vlewidth_bytesnumber(width);\n let EEW = load_width_bytes * 8;\n let EEW_pow = vlewidth_pow(width);\n let SEW_pow = get_sew_pow();\n let LMUL_pow = get_lmul_pow();\n let EMUL_pow = EEW_pow - SEW_pow + LMUL_pow;\n let num_elem = get_num_elem(EMUL_pow, EEW);\n let nf_int = nfields_int(nf);\n\n if illegal_store(nf_int, EEW, EMUL_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vssseg(nf_int, vm, vs3, load_width_bytes, rs1, rs2, EMUL_pow, num_elem)\n}", "description": "TBD" }, { "mnemonic": "vssub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssub.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssubu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vssubu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsub.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vsuxei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg2ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg2ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg2ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg2ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg3ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg3ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg3ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg3ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg4ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg4ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg4ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg4ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg5ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg5ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg5ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg5ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg6ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg6ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg6ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg6ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg7ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg7ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg7ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg7ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg8ei16.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg8ei32.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg8ei64.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vsuxseg8ei8.v", "name": "TBD", "operands": [ { "name": "nf", "type": "bits(3)" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "width", "type": "vlewidth" }, { "name": "vs3", "type": "regidx" } ], "syntax": "vs3,(rs1),vs2vm", "format": "TBD", "fields": [ { "field": "nf", "size": 3 }, { "field": "0b0", "size": 1 }, { "field": "0b01", "size": 2 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "encdec_vlewidth(width)", "size": 3 }, { "field": "vs3", "size": 5 }, { "field": "0b0100111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let EEW_index_pow = vlewidth_pow(width);\n let EEW_index_bytes = vlewidth_bytesnumber(width);\n let EEW_data_pow = get_sew_pow();\n let EEW_data_bytes = get_sew_bytes();\n let EMUL_data_pow = get_lmul_pow();\n let EMUL_index_pow = EEW_index_pow - EEW_data_pow + EMUL_data_pow;\n let num_elem = get_num_elem(EMUL_data_pow, EEW_data_bytes * 8); /* number of data and indices are the same */\n let nf_int = nfields_int(nf);\n\n if illegal_indexed_store(nf_int, EEW_index_bytes * 8, EMUL_index_pow, EMUL_data_pow) then { handle_illegal(); return RETIRE_FAIL };\n\n process_vsxseg(nf_int, vm, vs3, EEW_index_bytes, EEW_data_bytes, EMUL_index_pow, EMUL_data_pow, rs1, vs2, num_elem, 1)\n}", "description": "TBD" }, { "mnemonic": "vwadd.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwadd.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwadd.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwadd.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen)\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwaddu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwaddu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwaddu.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwaddu.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen)\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmacc.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVV_VWMACC => to_bits(SEW_widen, signed(vs1_val[i]) * signed(vs2_val[i])) + vd_val[i],\n WMVV_VWMACCU => to_bits(SEW_widen, unsigned(vs1_val[i]) * unsigned(vs2_val[i])) + vd_val[i],\n WMVV_VWMACCSU => to_bits(SEW_widen, signed(vs1_val[i]) * unsigned(vs2_val[i]))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmacc.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVX_VWMACCU => (to_bits(SEW_widen, unsigned(rs1_val) * unsigned(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACC => (to_bits(SEW_widen, signed(rs1_val) * signed(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACCUS => (to_bits(SEW_widen, unsigned(rs1_val) * signed(vs2_val[i]) ))+ vd_val[i],\n WMVX_VWMACCSU => (to_bits(SEW_widen, signed(rs1_val) * unsigned(vs2_val[i]) ))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmaccsu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVV_VWMACC => to_bits(SEW_widen, signed(vs1_val[i]) * signed(vs2_val[i])) + vd_val[i],\n WMVV_VWMACCU => to_bits(SEW_widen, unsigned(vs1_val[i]) * unsigned(vs2_val[i])) + vd_val[i],\n WMVV_VWMACCSU => to_bits(SEW_widen, signed(vs1_val[i]) * unsigned(vs2_val[i]))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmaccsu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVX_VWMACCU => (to_bits(SEW_widen, unsigned(rs1_val) * unsigned(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACC => (to_bits(SEW_widen, signed(rs1_val) * signed(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACCUS => (to_bits(SEW_widen, unsigned(rs1_val) * signed(vs2_val[i]) ))+ vd_val[i],\n WMVX_VWMACCSU => (to_bits(SEW_widen, signed(rs1_val) * unsigned(vs2_val[i]) ))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmaccu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVV_VWMACC => to_bits(SEW_widen, signed(vs1_val[i]) * signed(vs2_val[i])) + vd_val[i],\n WMVV_VWMACCU => to_bits(SEW_widen, unsigned(vs1_val[i]) * unsigned(vs2_val[i])) + vd_val[i],\n WMVV_VWMACCSU => to_bits(SEW_widen, signed(vs1_val[i]) * unsigned(vs2_val[i]))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmaccu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVX_VWMACCU => (to_bits(SEW_widen, unsigned(rs1_val) * unsigned(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACC => (to_bits(SEW_widen, signed(rs1_val) * signed(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACCUS => (to_bits(SEW_widen, unsigned(rs1_val) * signed(vs2_val[i]) ))+ vd_val[i],\n WMVX_VWMACCSU => (to_bits(SEW_widen, signed(rs1_val) * unsigned(vs2_val[i]) ))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmaccus.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wmvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,rs1,vs2vm", "format": "TBD", "fields": [ { "field": "encdec_wmvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WMVX_VWMACCU => (to_bits(SEW_widen, unsigned(rs1_val) * unsigned(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACC => (to_bits(SEW_widen, signed(rs1_val) * signed(vs2_val[i]) )) + vd_val[i],\n WMVX_VWMACCUS => (to_bits(SEW_widen, unsigned(rs1_val) * signed(vs2_val[i]) ))+ vd_val[i],\n WMVX_VWMACCSU => (to_bits(SEW_widen, signed(rs1_val) * unsigned(vs2_val[i]) ))+ vd_val[i]\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmul.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmul.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmulsu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmulsu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmulu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwmulu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwredsum.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rivvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rivvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW_widen); /* vd regardless of LMUL setting */\n\n if illegal_reduction_widen(SEW_widen, LMUL_pow_widen) then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('o)) = read_vreg(num_elem_vd, SEW_widen, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('o) = read_single_element(SEW_widen, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n let elem : bits('o) = match funct6 {\n IVV_VWREDSUMU => to_bits(SEW_widen, unsigned(vs2_val[i])),\n IVV_VWREDSUM => to_bits(SEW_widen, signed(vs2_val[i]))\n };\n sum = sum + elem\n }\n };\n\n write_single_element(SEW_widen, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwredsumu.vs", "name": "TBD", "operands": [ { "name": "funct6", "type": "rivvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_rivvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n let num_elem_vs = get_num_elem(LMUL_pow, SEW);\n let num_elem_vd = get_num_elem(0, SEW_widen); /* vd regardless of LMUL setting */\n\n if illegal_reduction_widen(SEW_widen, LMUL_pow_widen) then { handle_illegal(); return RETIRE_FAIL };\n\n if unsigned(vl) == 0 then return RETIRE_SUCCESS; /* if vl=0, no operation is performed */\n\n let 'n = num_elem_vs;\n let 'd = num_elem_vd;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem_vs, vm, 0b00000);\n let vd_val : vector('d, dec, bits('o)) = read_vreg(num_elem_vd, SEW_widen, 0, vd);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem_vs, SEW, LMUL_pow, vs2);\n let mask : vector('n, dec, bool) = init_masked_source(num_elem_vs, LMUL_pow, vm_val);\n\n sum : bits('o) = read_single_element(SEW_widen, 0, vs1); /* vs1 regardless of LMUL setting */\n foreach (i from 0 to (num_elem_vs - 1)) {\n if mask[i] then {\n let elem : bits('o) = match funct6 {\n IVV_VWREDSUMU => to_bits(SEW_widen, unsigned(vs2_val[i])),\n IVV_VWREDSUM => to_bits(SEW_widen, signed(vs2_val[i]))\n };\n sum = sum + elem\n }\n };\n\n write_single_element(SEW_widen, 0, vd, sum);\n /* other elements in vd are treated as tail elements, currently remain unchanged */\n /* TODO: configuration support for agnostic behavior */\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsub.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsub.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsub.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsub.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen)\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsubu.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen)) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WVV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WVV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WVV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i])),\n WVV_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(vs1_val[i])),\n WVV_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(vs1_val[i])),\n WVV_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsubu.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WVX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WVX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WVX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WVX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val)),\n WVX_VWMUL => to_bits(SEW_widen, signed(vs2_val[i]) * signed(rs1_val)),\n WVX_VWMULU => to_bits(SEW_widen, unsigned(vs2_val[i]) * unsigned(rs1_val)),\n WVX_VWMULSU => to_bits(SEW_widen, signed(vs2_val[i]) * unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsubu.wv", "name": "TBD", "operands": [ { "name": "funct6", "type": "wvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_wvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen) |\n not(valid_reg_overlap(vs1, vd, LMUL_pow, LMUL_pow_widen))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WV_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(vs1_val[i])),\n WV_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(vs1_val[i])),\n WV_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(vs1_val[i])),\n WV_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(vs1_val[i]))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vwsubu.wx", "name": "TBD", "operands": [ { "name": "funct6", "type": "wxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_wxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b110", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_widen = SEW * 2;\n let LMUL_pow_widen = LMUL_pow + 1;\n\n if illegal_variable_width(vd, vm, SEW_widen, LMUL_pow_widen)\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_widen;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_widen, LMUL_pow_widen, vs2);\n result : vector('n, dec, bits('o)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW_widen, LMUL_pow_widen, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n WX_VADD => to_bits(SEW_widen, signed(vs2_val[i]) + signed(rs1_val)),\n WX_VSUB => to_bits(SEW_widen, signed(vs2_val[i]) - signed(rs1_val)),\n WX_VADDU => to_bits(SEW_widen, unsigned(vs2_val[i]) + unsigned(rs1_val)),\n WX_VSUBU => to_bits(SEW_widen, unsigned(vs2_val[i]) - unsigned(rs1_val))\n }\n }\n };\n\n write_vreg(num_elem, SEW_widen, LMUL_pow_widen, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vxor.vi", "name": "TBD", "operands": [ { "name": "funct6", "type": "vifunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "simm", "type": "bits(5)" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,simmvm", "format": "TBD", "fields": [ { "field": "encdec_vifunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "simm", "size": 5 }, { "field": "0b011", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let imm_val : bits('m) = sign_extend(simm);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VI_VADD => vs2_val[i] + imm_val,\n VI_VRSUB => imm_val - vs2_val[i],\n VI_VAND => vs2_val[i] & imm_val,\n VI_VOR => vs2_val[i] | imm_val,\n VI_VXOR => vs2_val[i] ^ imm_val,\n VI_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, imm_val) ),\n VI_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, imm_val) ),\n VI_VSLL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] << shift_amount\n },\n VI_VSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n vs2_val[i] >> shift_amount\n },\n VI_VSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VI_VSSRL => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VI_VSSRA => {\n let shift_amount = get_shift_amount(zero_extend('m, simm), SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vxor.vv", "name": "TBD", "operands": [ { "name": "funct6", "type": "vvfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,vs1vm", "format": "TBD", "fields": [ { "field": "encdec_vvfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vs1", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW_pow = get_sew_pow();\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let VLEN_pow = get_vlen_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vs1_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs1);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VV_VADD => vs2_val[i] + vs1_val[i],\n VV_VSUB => vs2_val[i] - vs1_val[i],\n VV_VAND => vs2_val[i] & vs1_val[i],\n VV_VOR => vs2_val[i] | vs1_val[i],\n VV_VXOR => vs2_val[i] ^ vs1_val[i],\n VV_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, vs1_val[i])),\n VV_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, vs1_val[i])),\n VV_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(vs1_val[i]) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, vs1_val[i]))\n },\n VV_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, vs1_val[i])),\n VV_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(vs1_val[i]));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VV_VSLL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] << shift_amount\n },\n VV_VSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n vs2_val[i] >> shift_amount\n },\n VV_VSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VV_VSSRL => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VV_VSSRA => {\n let shift_amount = get_shift_amount(vs1_val[i], SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VV_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(vs1_val[i]))),\n VV_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(vs1_val[i]))),\n VV_VRGATHER => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n let idx = unsigned(vs1_val[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n },\n VV_VRGATHEREI16 => {\n if (vs1 == vd | vs2 == vd) then { handle_illegal(); return RETIRE_FAIL };\n /* vrgatherei16.vv uses SEW/LMUL for the data in vs2 but EEW=16 and EMUL = (16/SEW)*LMUL for the indices in vs1 */\n let vs1_new : vector('n, dec, bits(16)) = read_vreg(num_elem, 16, 4 + LMUL_pow - SEW_pow, vs1);\n let idx = unsigned(vs1_new[i]);\n let VLMAX = int_power(2, LMUL_pow + VLEN_pow - SEW_pow);\n assert(VLMAX <= 'n);\n if idx < VLMAX then vs2_val[idx] else zeros()\n }\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vxor.vx", "name": "TBD", "operands": [ { "name": "funct6", "type": "vxfunct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2,rs1vm", "format": "TBD", "fields": [ { "field": "encdec_vxfunct6(funct6)", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n\n if illegal_normal(vd, vm) then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let rs1_val : bits('m) = get_scalar(rs1, SEW);\n let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VX_VADD => vs2_val[i] + rs1_val,\n VX_VSUB => vs2_val[i] - rs1_val,\n VX_VRSUB => rs1_val - vs2_val[i],\n VX_VAND => vs2_val[i] & rs1_val,\n VX_VOR => vs2_val[i] | rs1_val,\n VX_VXOR => vs2_val[i] ^ rs1_val,\n VX_VSADDU => unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) + zero_extend('m + 1, rs1_val) ),\n VX_VSADD => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) + sign_extend('m + 1, rs1_val) ),\n VX_VSSUBU => {\n if unsigned(vs2_val[i]) < unsigned(rs1_val) then zeros()\n else unsigned_saturation('m, zero_extend('m + 1, vs2_val[i]) - zero_extend('m + 1, rs1_val) )\n },\n VX_VSSUB => signed_saturation('m, sign_extend('m + 1, vs2_val[i]) - sign_extend('m + 1, rs1_val) ),\n VX_VSMUL => {\n let result_mul = to_bits('m * 2, signed(vs2_val[i]) * signed(rs1_val));\n let rounding_incr = get_fixed_rounding_incr(result_mul, 'm - 1);\n let result_wide = (result_mul >> ('m - 1)) + zero_extend('m * 2, rounding_incr);\n signed_saturation('m, result_wide['m..0])\n },\n VX_VSLL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] << shift_amount\n },\n VX_VSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n vs2_val[i] >> shift_amount\n },\n VX_VSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW)\n },\n VX_VSSRL => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n (vs2_val[i] >> shift_amount) + zero_extend('m, rounding_incr)\n },\n VX_VSSRA => {\n let shift_amount = get_shift_amount(rs1_val, SEW);\n let rounding_incr = get_fixed_rounding_incr(vs2_val[i], shift_amount);\n let v_double : bits('m * 2) = sign_extend(vs2_val[i]);\n slice(v_double >> shift_amount, 0, SEW) + zero_extend('m, rounding_incr)\n },\n VX_VMINU => to_bits(SEW, min(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMIN => to_bits(SEW, min(signed(vs2_val[i]), signed(rs1_val))),\n VX_VMAXU => to_bits(SEW, max(unsigned(vs2_val[i]), unsigned(rs1_val))),\n VX_VMAX => to_bits(SEW, max(signed(vs2_val[i]), signed(rs1_val)))\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vzext.vf2", "name": "TBD", "operands": [ { "name": "funct6", "type": "vext2funct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vext2_vs1(funct6)", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_half = SEW / 2;\n let LMUL_pow_half = LMUL_pow - 1;\n\n if illegal_variable_width(vd, vm, SEW_half, LMUL_pow_half) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_half, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_half;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_half, LMUL_pow_half, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW > SEW_half);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VEXT2_ZVF2 => zero_extend(vs2_val[i]),\n VEXT2_SVF2 => sign_extend(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vzext.vf4", "name": "TBD", "operands": [ { "name": "funct6", "type": "vext4funct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vext4_vs1(funct6)", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_quart = SEW / 4;\n let LMUL_pow_quart = LMUL_pow - 2;\n\n if illegal_variable_width(vd, vm, SEW_quart, LMUL_pow_quart) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_quart, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_quart;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_quart, LMUL_pow_quart, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW > SEW_quart);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VEXT4_ZVF4 => zero_extend(vs2_val[i]),\n VEXT4_SVF4 => sign_extend(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "vzext.vf8", "name": "TBD", "operands": [ { "name": "funct6", "type": "vext8funct6" }, { "name": "vm", "type": "bits(1)" }, { "name": "vs2", "type": "regidx" }, { "name": "vd", "type": "regidx" } ], "syntax": "vd,vs2vm", "format": "TBD", "fields": [ { "field": "0b010010", "size": 6 }, { "field": "vm", "size": 1 }, { "field": "vs2", "size": 5 }, { "field": "vext8_vs1(funct6)", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "vd", "size": 5 }, { "field": "0b1010111", "size": 7 } ], "extensions": [ "V" ], "function": "{\n let SEW = get_sew();\n let LMUL_pow = get_lmul_pow();\n let num_elem = get_num_elem(LMUL_pow, SEW);\n let SEW_eighth = SEW / 8;\n let LMUL_pow_eighth = LMUL_pow - 3;\n\n if illegal_variable_width(vd, vm, SEW_eighth, LMUL_pow_eighth) |\n not(valid_reg_overlap(vs2, vd, LMUL_pow_eighth, LMUL_pow))\n then { handle_illegal(); return RETIRE_FAIL };\n\n let 'n = num_elem;\n let 'm = SEW;\n let 'o = SEW_eighth;\n\n let vm_val : vector('n, dec, bool) = read_vmask(num_elem, vm, 0b00000);\n let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);\n let vs2_val : vector('n, dec, bits('o)) = read_vreg(num_elem, SEW_eighth, LMUL_pow_eighth, vs2);\n result : vector('n, dec, bits('m)) = undefined;\n mask : vector('n, dec, bool) = undefined;\n\n (result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);\n\n assert(SEW > SEW_eighth);\n foreach (i from 0 to (num_elem - 1)) {\n if mask[i] then {\n result[i] = match funct6 {\n VEXT8_ZVF8 => zero_extend(vs2_val[i]),\n VEXT8_SVF8 => sign_extend(vs2_val[i])\n }\n }\n };\n\n write_vreg(num_elem, SEW, LMUL_pow, vd, result);\n vstart = zeros();\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "wfi", "name": "TBD", "operands": [], "syntax": "", "format": "TBD", "fields": [ { "field": "0b000100000101", "size": 12 }, { "field": "0b00000", "size": 5 }, { "field": "0b000", "size": 3 }, { "field": "0b00000", "size": 5 }, { "field": "0b1110011", "size": 7 } ], "extensions": [], "function": "match cur_privilege {\n Machine => { platform_wfi(); RETIRE_SUCCESS },\n Supervisor => if mstatus.TW() == 0b1\n then { handle_illegal(); RETIRE_FAIL }\n else { platform_wfi(); RETIRE_SUCCESS },\n User => { handle_illegal(); RETIRE_FAIL }\n }", "description": "TBD" }, { "mnemonic": "xnor", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "brop_zbb" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0110000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbb", "Zbkb" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ANDN => rs1_val & ~(rs2_val),\n RISCV_ORN => rs1_val | ~(rs2_val),\n RISCV_XNOR => ~(rs1_val ^ rs2_val),\n RISCV_MAX => to_bits(sizeof(xlen), max(signed(rs1_val), signed(rs2_val))),\n RISCV_MAXU => to_bits(sizeof(xlen), max(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_MIN => to_bits(sizeof(xlen), min(signed(rs1_val), signed(rs2_val))),\n RISCV_MINU => to_bits(sizeof(xlen), min(unsigned(rs1_val), unsigned(rs2_val))),\n RISCV_ROL => if sizeof(xlen) == 32\n then rs1_val <<< rs2_val[4..0]\n else rs1_val <<< rs2_val[5..0],\n RISCV_ROR => if sizeof(xlen) == 32\n then rs1_val >>> rs2_val[4..0]\n else rs1_val >>> rs2_val[5..0]\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "xor", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "rop" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0100000", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b101", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n let result : xlenbits = match op {\n RISCV_ADD => rs1_val + rs2_val,\n RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),\n RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),\n RISCV_AND => rs1_val & rs2_val,\n RISCV_OR => rs1_val | rs2_val,\n RISCV_XOR => rs1_val ^ rs2_val,\n RISCV_SLL => if sizeof(xlen) == 32\n then rs1_val << (rs2_val[4..0])\n else rs1_val << (rs2_val[5..0]),\n RISCV_SRL => if sizeof(xlen) == 32\n then rs1_val >> (rs2_val[4..0])\n else rs1_val >> (rs2_val[5..0]),\n RISCV_SUB => rs1_val - rs2_val,\n RISCV_SRA => if sizeof(xlen) == 32\n then shift_right_arith32(rs1_val, rs2_val[4..0])\n else shift_right_arith64(rs1_val, rs2_val[5..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe R-type (Register-type) instruction format is used for operations\nthat involve three registers. The specific operation is determined\nby the opcode and funct7 fields. The result is written to the\ndestination register (rd), and the source operands are specified\nby the source registers (rs1 and rs2). The format is common for\narithmetic, logical, and shift operations.\n " }, { "mnemonic": "xori", "name": "TBD", "operands": [ { "name": "imm", "type": "bits(12)" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "iop" } ], "syntax": "rd,rs1,imm", "format": "TBD", "fields": [ { "field": "imm", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "encdec_iop(op)", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [], "function": "{\n let rs1_val = X(rs1);\n let immext : xlenbits = sign_extend(imm);\n let result : xlenbits = match op {\n RISCV_ADDI => rs1_val + immext,\n RISCV_SLTI => zero_extend(bool_to_bits(rs1_val <_s immext)),\n RISCV_SLTIU => zero_extend(bool_to_bits(rs1_val <_u immext)),\n RISCV_ANDI => rs1_val & immext,\n RISCV_ORI => rs1_val | immext,\n RISCV_XORI => rs1_val ^ immext\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "\nThe ITYPE instruction operates on an immediate value, adding, comparing, or\nperforming bitwise operations with the contents of register rs1.\nThe immediate value, rs1, and the operation code (iop) determine the operation.\nThe result is stored in register rd.\nThe supported immediate operations (iop) include:\n - \"addi\" : Add immediate\n - \"slti\" : Set less than immediate (signed)\n - \"sltiu\" : Set less than immediate (unsigned)\n - \"andi\" : AND immediate\n - \"ori\" : OR immediate\n - \"xori\" : XOR immediate\n *\nNote: The immediate value is sign-extended before performing the operation.\n " }, { "mnemonic": "xperm4", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b010", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbkx" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen) - 4) by 4) {\n let index = unsigned(rs2_val[i+3..i]);\n result[i+3..i] = if 4*index < sizeof(xlen)\n then rs1_val[4*index+3..4*index]\n else zeros()\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "xperm8", "name": "TBD", "operands": [ { "name": "rs2", "type": "regidx" }, { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1,rs2", "format": "TBD", "fields": [ { "field": "0b0010100", "size": 7 }, { "field": "rs2", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0110011", "size": 7 } ], "extensions": [ "Zbkx" ], "function": "{\n let rs1_val = X(rs1);\n let rs2_val = X(rs2);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen) - 8) by 8) {\n let index = unsigned(rs2_val[i+7..i]);\n result[i+7..i] = if 8*index < sizeof(xlen)\n then rs1_val[8*index+7..8*index]\n else zeros()\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "zext.h", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" }, { "name": "op", "type": "extop_zbb" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b0000100", "size": 7 }, { "field": "0b00000", "size": 5 }, { "field": "rs1", "size": 5 }, { "field": "0b100", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0111011", "size": 7 } ], "extensions": [ "Zbb" ], "function": "{\n let rs1_val = X(rs1);\n let result : xlenbits = match op {\n RISCV_SEXTB => sign_extend(rs1_val[7..0]),\n RISCV_SEXTH => sign_extend(rs1_val[15..0]),\n RISCV_ZEXTH => zero_extend(rs1_val[15..0])\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" }, { "mnemonic": "zip", "name": "TBD", "operands": [ { "name": "rs1", "type": "regidx" }, { "name": "rd", "type": "regidx" } ], "syntax": "rd,rs1", "format": "TBD", "fields": [ { "field": "0b000010001111", "size": 12 }, { "field": "rs1", "size": 5 }, { "field": "0b001", "size": 3 }, { "field": "rd", "size": 5 }, { "field": "0b0010011", "size": 7 } ], "extensions": [ "Zbkb" ], "function": "{\n assert(sizeof(xlen) == 32);\n let rs1_val = X(rs1);\n result : xlenbits = zeros();\n foreach (i from 0 to (sizeof(xlen_bytes)*4 - 1)) {\n result[i*2] = rs1_val[i];\n result[i*2 + 1] = rs1_val[i + sizeof(xlen_bytes)*4];\n };\n X(rd) = result;\n RETIRE_SUCCESS\n}", "description": "TBD" } ], "formats": [ "I", "R", "TBD" ], "extensions": [ "A", "C", "D", "F", "M", "V", "Zba", "Zbb", "Zbc", "Zbkb", "Zbkc", "Zbkx", "Zbs", "Zfa", "Zfh", "Zicond", "Zknd", "Zkne", "Zknh", "Zksed", "Zksh" ] }