Exemple #1
0
        public void ParseJal(RvcPayload payload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.JAL");

            instructionPayload.Rd = 1;
            instructionPayload.SignedImmediate = DecodeJalOffset(payload.Immediate);
        }
Exemple #2
0
        public void ParseLui(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.LUI loads the non-zero 6-bit immediate field into bits 17–12 of the destination register, clears the
            // bottom 12 bits, and sign-extends bit 17 into all higher bits of the destination.C.LUI expands into
            // lui rd, nzimm[17:12].C.LUI is only valid when rd̸ = { x0, x2 }, and when the immediate is not
            // equal to zero. The code points with nzimm = 0 are reserved; the remaining code points with rd = x0
            // are HINTs; and the remaining code points with rd = x2 correspond to the C.ADDI16SP instruction.
            //

            Logger.Info("Parsing C.LUI");

            // nzimm[17...12] = payload.immediate

            if (payload.Rd == 0 || payload.Rd == 2)
            {
                throw new RvcFormatException("C.LUI does not accept RD=0 or RD=2");
            }

            instructionPayload.Rd = payload.Rd;
            uint uimmediate = Convert.ToUInt32(payload.Immediate << 12);

            // Expand Bit 17 to the higher ones (31....17)
            uint bitmask = 0xFFFFC000;
            uint b17     = 0x020000;

            if ((uimmediate & b17) == b17)
            {
                uimmediate |= bitmask;
            }

            instructionPayload.UnsignedImmediate = uimmediate;
        }
Exemple #3
0
        public void ParseSrli(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.SRLI is a CB-format instruction that performs a logical right shift of the value in register rd ′
            // then writes the result to rd ′. The shift amount is encoded in the shamt field.For RV128C, a shift
            // amount of zero is used to encode a shift of 64.Furthermore, the shift amount is sign - extended for
            // RV128C, and so the legal shift amounts are 1–31, 64, and 96–127.C.SRLI expands into srli rd ′,
            // rd ′, shamt[5:0], except for RV128C with shamt = 0, which expands to srli rd ′, rd ′, 64.
            //
            // For RV32C, shamt[5] must be zero; the code points with shamt[5]=1 are reserved for custom
            // extensions.For RV32C and RV64C, the shift amount must be non - zero; the code points with
            // shamt = 0 are HINTs.

            Logger.Info("Parsing C.SRLI");

            if ((payload.Immediate & 0x20) == 0x20)
            {
                throw new RvcFormatException("Bit 5 for the RV32C C.SRLI must be zero");
            }

            // SRLI rd`,rd`,shamt[5:0]
            // srli    rd rs1 31..26=0  shamt 14..12=5 6..2=0x04 1..0=3


            instructionPayload.Funct3          = 5;
            instructionPayload.Rs1             = payload.Rs1;
            instructionPayload.Rd              = payload.Rd;
            instructionPayload.SignedImmediate = payload.Immediate;
        }
Exemple #4
0
        public void ParseCaGeneric(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // These instructions use the CA format.
            //
            // C.AND computes the bitwise AND of the values in registers rd ′ and rs2 ′, then writes the result to
            // register rd ′. C.AND expands into and rd ′, rd ′, rs2 ′.
            //
            // C.OR computes the bitwise OR of the values in registers rd ′ and rs2 ′, then writes the result to
            // register rd ′. C.OR expands into or rd ′, rd ′, rs2 ′.
            //
            // C.XOR computes the bitwise XOR of the values in registers rd ′ and rs2 ′, then writes the result to
            // register rd ′. C.XOR expands into xor rd ′, rd ′, rs2 ′.
            //
            // C.SUB subtracts the value in register rs2 ′ from the value in register rd ′, then writes the result to
            // register rd ′. C.SUB expands into sub rd ′, rd ′, rs2 ′.

            // add rd rs1 rs2 31..25 = 0  14..12 = 0 6..2 = 0x0C 1..0 = 3
            // sub rd rs1 rs2 31..25 = 32 14..12 = 0 6..2 = 0x0C 1..0 = 3
            // sll rd rs1 rs2 31..25 = 0  14..12 = 1 6..2 = 0x0C 1..0 = 3
            // slt rd rs1 rs2 31..25 = 0  14..12 = 2 6..2 = 0x0C 1..0 = 3
            // sltu rd rs1 rs2 31..25 = 0  14..12 = 3 6..2 = 0x0C 1..0 = 3
            // xor rd rs1 rs2 31..25 = 0  14..12 = 4 6..2 = 0x0C 1..0 = 3
            // srl rd rs1 rs2 31..25 = 0  14..12 = 5 6..2 = 0x0C 1..0 = 3
            // sra rd rs1 rs2 31..25 = 32 14..12 = 5 6..2 = 0x0C 1..0 = 3
            // or rd rs1 rs2 31..25 = 0  14..12 = 6 6..2 = 0x0C 1..0 = 3
            // and rd rs1 rs2 31..25 = 0  14..12 = 7 6..2 = 0x0C 1..0 = 3

            Logger.Info("Parsing C.SUB / C.XOR / C.OR / C.AND");

            instructionPayload.Rs1 = payload.Rs1;
            instructionPayload.Rs2 = payload.Rs2;
            instructionPayload.Rd  = payload.Rd;

            if (payload.CAMode == 0)
            {
                // C.SUB
                // f3 = 0
                instructionPayload.Funct7 = 0x32;
            }

            if (payload.CAMode == 1)
            {
                // C.XOR
                instructionPayload.Funct3 = 4;
            }

            if (payload.CAMode == 2)
            {
                // C.OR
                instructionPayload.Funct3 = 6;
            }

            if (payload.CAMode == 3)
            {
                // C.AND
                instructionPayload.Funct3 = 7;
            }
        }
Exemple #5
0
        private InstructionPayload DecodeTypeI(Instruction instruction, IEnumerable <byte> inst32Coding)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            var payload = new InstructionPayload(instruction, inst32Coding);
            var bytes   = inst32Coding;
            int workingBuffer;

            // b4   (bit 0...7)
            // b3   (bit 8...15)
            // b2   (bit 16...23)
            // b1   (bit 24...31)
            //
            // Opcode   = 0  ... 6
            // rd       = 7  ... 11
            // funct3   = 12 ... 14
            // rs1      = 15 ... 19
            // Imm.     = 20 ... 31


            var b4 = bytes.ElementAt(3);
            var b3 = bytes.ElementAt(2);
            var b2 = bytes.ElementAt(1);

            // decode funct3
            workingBuffer   = b2;
            workingBuffer >>= 4;
            int funct3 = Convert.ToInt32(workingBuffer & 0x7);

            // decode rs1
            workingBuffer   = b3;
            workingBuffer <<= 8;
            workingBuffer  |= b2;
            //  working Buffer = b3b2;
            workingBuffer >>= 7;
            workingBuffer  &= 0x1F;
            int rs1 = Convert.ToInt32(workingBuffer);

            // decode immediate
            workingBuffer   = b4;
            workingBuffer <<= 8;
            workingBuffer  |= b3;
            workingBuffer >>= 4;

            int immediate = MathHelper.GetSignedInteger(workingBuffer, instruction.Type);

            var rd = GetRd(inst32Coding);

            payload.Rd                      = rd;
            payload.Funct3                  = funct3;
            payload.Rs1                     = rs1;
            payload.SignedImmediate         = immediate;
            payload.UnsignedImmediate       = Convert.ToUInt32(workingBuffer);
            payload.SignedImmediateComplete = Convert.ToInt32(workingBuffer);
            return(payload);
        }
Exemple #6
0
        public void ParseSd(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.SD");

            instructionPayload.Funct3          = 3;
            instructionPayload.Rs1             = rvcPayload.Rs1;
            instructionPayload.Rs2             = rvcPayload.Rs2;
            instructionPayload.SignedImmediate = DecodeLoadStoreOffset(rvcPayload.Immediate);
        }
Exemple #7
0
        public void ParseSlli(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.SLLI");

            // slli    rd rs1 31..26=0  shamt 14..12=1 6..2=0x04 1..0=3
            instructionPayload.Rd              = rvcPayload.Rd;
            instructionPayload.Rs1             = rvcPayload.Rs1;
            instructionPayload.Funct3          = 1;
            instructionPayload.SignedImmediate = rvcPayload.Immediate;
        }
Exemple #8
0
        public void ParseLdSp(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.LDSP");

            // ld      rd rs1       imm12 14..12=3 6..2=0x00 1..0=3

            instructionPayload.Rd              = rvcPayload.Rd;
            instructionPayload.Rs1             = 2;
            instructionPayload.Funct3          = 3;
            instructionPayload.SignedImmediate = DecodeLoadStoreSpOffset(rvcPayload.Immediate);
        }
Exemple #9
0
        public void ParseLd(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.LD");
            // rs1
            // rd
            // Offset :  5 4 3 7 6 (scaled by 8 (3 2 1 0))

            instructionPayload.Funct3          = 3;
            instructionPayload.Rs1             = rvcPayload.Rs1;
            instructionPayload.Rd              = rvcPayload.Rd;
            instructionPayload.SignedImmediate = DecodeLoadStoreOffset(rvcPayload.Immediate);
        }
Exemple #10
0
        public void ParseSdSp(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.SDSP");

            // sd     imm12hi rs1 rs2 imm12lo 14..12=3 6..2=0x08 1..0=3

            instructionPayload.Rd              = rvcPayload.Rd;
            instructionPayload.Rs1             = 2;
            instructionPayload.Rs2             = rvcPayload.Rs2;
            instructionPayload.Funct3          = 3;
            instructionPayload.SignedImmediate = DecodeLoadStoreSpOffset(rvcPayload.Immediate);
        }
Exemple #11
0
        public void ParseSlli(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            // C.SLLI is a CI-format instruction that performs a logical left shift of the value in register rd then
            // writes the result to rd.The shift amount is encoded in the shamt field.

            Logger.Info("Parsing C.SLLI");

            instructionPayload.Rs1    = rvcPayload.Rs1;
            instructionPayload.Rd     = rvcPayload.Rd;
            instructionPayload.Funct3 = 1;
            // The type decoder automatically generated the correct order
            instructionPayload.SignedImmediate = rvcPayload.Immediate;
        }
Exemple #12
0
        public void ParseAddiW(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.AddiW");

            // addiw   rd rs1 imm12            14..12=0 6..2=0x06 1..0=3

            instructionPayload.Rd  = rvcPayload.Rd;
            instructionPayload.Rs1 = rvcPayload.Rs1;

            var immediate = MathHelper.GetSignedInteger(rvcPayload.Immediate, 5);

            instructionPayload.SignedImmediate = immediate;
        }
Exemple #13
0
        public void ParseAddi16Sp(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.ADDI16SP shares the opcode with C.LUI, but has a destination field of x2. C.ADDI16SP adds
            // the non-zero sign - extended 6 - bit immediate to the value in the stack pointer(sp = x2), where the
            // immediate is scaled to represent multiples of 16 in the range(-512,496). C.ADDI16SP is used
            // to adjust the stack pointer in procedure prologues and epilogues. It expands into addi x2, x2,
            // nzimm[9:4].C.ADDI16SP is only valid when nzimm̸ = 0; the code point with nzimm = 0 is reserved.
            //

            Logger.Info("Parsing C.ADDI16SP");

            instructionPayload.Rd  = 2;
            instructionPayload.Rs1 = 2;

            // b5
            int buffer    = payload.Immediate;
            int immediate = buffer & 0x01;

            immediate <<= 5;

            // 8 7
            buffer >>= 1;
            int b87 = buffer & 0x03;

            b87      <<= 7;
            immediate |= b87;

            // 6
            buffer >>= 2;
            int b6 = buffer & 0x01;

            b6       <<= 6;
            immediate |= b6;

            // 4
            buffer >>= 1;
            int b4 = buffer & 0x01;

            b4       <<= 4;
            immediate |= b4;

            // 9
            buffer >>= 1;
            int b9 = buffer & 0x01;

            b9       <<= 9;
            immediate |= b9;

            instructionPayload.SignedImmediate = immediate;
        }
Exemple #14
0
        public void ParseAddAndMv(RvcPayload payload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.MV / C.ADD");

            instructionPayload.Rd  = payload.Rd;
            instructionPayload.Rs2 = payload.Rs2;

            // F4 == 9 => C.ADD
            // F4 == 8 => C.MV und RS1 = x0
            if (payload.Funct4 == 9)
            {
                instructionPayload.Rs1 = payload.Rd;
            }
        }
Exemple #15
0
        public void ParseAddi(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.ADDI adds the non-zero sign-extended 6-bit immediate to the value in register rd then writes
            // the result to rd. C.ADDI expands into addi rd, rd, nzimm[5:0].C.ADDI is only valid when
            // rd̸ = x0 and nzimm̸ = 0.The code points with rd = x0 encode the C.NOP instruction; the remaining
            // code points with nzimm = 0 encode HINTs.
            //

            Logger.Info("Parsing C.ADDI");

            instructionPayload.Rd              = payload.Rd;
            instructionPayload.Rs1             = payload.Rs1;
            instructionPayload.SignedImmediate = payload.Immediate; // non-zero immediate.
        }
Exemple #16
0
        public void ParseBeqzAndBnez(RvcPayload payload, InstructionPayload instructionPayload, bool forEqual)
        {
            Logger.Info("Parsing C.BEQZ / C.BNEZ");

            if (forEqual)
            {
                instructionPayload.Funct3 = 0;
            }
            else
            {
                instructionPayload.Funct3 = 1;
            }

            instructionPayload.Rs1             = payload.Rs1;
            instructionPayload.SignedImmediate = DecodeCbOffset(payload.Immediate);
        }
Exemple #17
0
        public void ParseAndi(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.ANDI is a CB-format instruction that computes the bitwise AND of the value in register rd ′ and
            // the sign-extended 6 - bit immediate, then writes the result to rd ′. C.ANDI expands to andi rd ′,
            // rd ′, imm[5:0].
            //

            Logger.Info("Parsing C.ANDI");

            instructionPayload.Funct3 = 7;
            instructionPayload.Rs1    = payload.Rs1;
            instructionPayload.Rd     = payload.Rd;

            // Signed 6 Bit imm
            instructionPayload.SignedImmediate = MathHelper.GetSignedInteger(payload.Immediate, 5);
        }
Exemple #18
0
        private InstructionPayload DecodeTypeU(Instruction instruction, IEnumerable <byte> inst32Coding)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            var  payload = new InstructionPayload(instruction, inst32Coding);
            var  bytes   = inst32Coding;
            uint workingBuffer;

            // b4   (bit 0...7)
            // b3   (bit 8...15)
            // b2   (bit 16...23)
            // b1   (bit 24...31)
            //
            // Opcode   = 0  ... 6
            // rd       = 7  ... 11
            // funct3   = 12 ... 14
            // rs1      = 15 ... 19
            // Imm.     = 20 ... 31


            var b4 = bytes.ElementAt(3);
            var b3 = bytes.ElementAt(2);
            var b2 = bytes.ElementAt(1);

            // fill the buffer with b4 b3 b2
            workingBuffer   = b4;
            workingBuffer <<= 8;
            workingBuffer  |= b3;
            workingBuffer <<= 8;
            workingBuffer  |= b2;

            // shift to the right and that's it. Signed bit ??
            workingBuffer >>= 4;
            uint immediate = workingBuffer;


            var rd = GetRd(inst32Coding);

            payload.Rd = rd;
            payload.UnsignedImmediate = immediate;
            return(payload);
        }
Exemple #19
0
        public void ParseJrAndJalr(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            //
            // F4 = 8
            // C.JR (jump register) performs an unconditional control transfer to the address in register rs1.
            // C.JR expands to jalr x0, 0(rs1).C.JR is only valid when rs1̸ = x0; the code point with rs1 = x0
            // is reserved.
            //
            // F4 = 9
            // C.JALR (jump and link register) performs the same operation as C.JR, but additionally writes the
            // address of the instruction following the jump(pc + 2) to the link register, x1. C.JALR expands to
            // jalr x1, 0(rs1).C.JALR is only valid when rs1̸ = x0; the code point with rs1 = x0 corresponds
            // to the C.EBREAK instruction.
            //
            //

            Logger.Info("Parsing C.JR / C.JALR with F4 = {f4:X}", rvcPayload.Funct4);

            var f4 = rvcPayload.Funct4;

            if (f4 == 8)
            {
                // C.JR
                if (rvcPayload.Rs1 == 0)
                {
                    throw new RvcFormatException("Invalid C.JR coding. Rs1 cannot be 0");
                }

                instructionPayload.Rs1 = rvcPayload.Rs1;
            }

            if (f4 == 9)
            {
                // C.JALR
                if (rvcPayload.Rs1 == 0)
                {
                    throw new RvcFormatException("Invalid C.JALR coding. Rs1 cannot be 0");
                }

                instructionPayload.Rd  = 1;
                instructionPayload.Rs1 = rvcPayload.Rs1;
            }

            // RvcFormatException
        }
Exemple #20
0
        public void ParseLw(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            //
            // C.LW loads a 32-bit value from memory into register rd ′. It computes an effective address by
            // adding the zero - extended offset, scaled by 4, to the base address in register rs1 ′. It expands to lw
            // rd ′, offset[6:2](rs1 ′).
            //

            Logger.Info("Parsing C.LW");

            instructionPayload.Rd     = rvcPayload.Rd;
            instructionPayload.Rs1    = rvcPayload.Rs1;
            instructionPayload.Funct3 = 2;

            int immediate = DecodeLoadStoreW(rvcPayload.Immediate);

            instructionPayload.SignedImmediate = immediate;
        }
Exemple #21
0
        public void ParseSw(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            //
            // C.SW stores a 32-bit value in register rs2 ′ to memory. It computes an effective address by adding
            // the zero-extended offset, scaled by 4, to the base address in register rs1 ′. It expands to sw rs2 ′,
            // offset[6:2](rs1 ′).
            //

            Logger.Info("Parsing C.SP");

            instructionPayload.Funct3 = 2;
            instructionPayload.Rs2    = rvcPayload.Rs2; // The source
            instructionPayload.Rs1    = rvcPayload.Rs1; // The register pointing to the memory address

            int immediate = DecodeLoadStoreW(rvcPayload.Immediate);

            instructionPayload.SignedImmediate = immediate;
        }
Exemple #22
0
        public void ParseAddi4Spn(RvcPayload payload, InstructionPayload instructionPayload)
        {
            // C.ADDI4SPN is a CIW-format instruction that adds a zero-extended non-zero immediate, scaled
            // by 4, to the stack pointer, x2, and writes the result to rd ′. This instruction is used to generate
            // pointers to stack-allocated variables, and expands to addi rd ′, x2, nzuimm[9:2].C.ADDI4SPN
            // is only valid when nzuimm̸ = 0; the code points with nzuimm = 0 are reserved.

            Logger.Info("Parsing C.ADDI4SPN");

            // nzuimm  5 4 9 8 7 6 2 3

            instructionPayload.Rs1    = 2;
            instructionPayload.Rd     = payload.Rd;
            instructionPayload.Funct3 = 0;

            // 3
            int buffer    = payload.Immediate;
            int immediate = buffer & 0x01;
            int current;

            immediate <<= 3;

            // 2
            buffer   >>= 1;
            current    = buffer & 0x01;
            current  <<= 2;
            immediate |= current;

            // 9 8 7 6
            buffer   >>= 1;
            current    = buffer & 0x0F;
            current  <<= 6;
            immediate |= current;

            // 5 4
            buffer   >>= 4;
            current    = buffer & 0x03;
            current  <<= 4;
            immediate |= current;


            instructionPayload.SignedImmediate = immediate;
        }
Exemple #23
0
        public void ParseAddWSubW(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            Logger.Info("Parsing C.AddW / C.SubW");

            // addw rd rs1 rs2 31..25 = 0  14..12 = 0 6..2 = 0x0E 1..0 = 3
            // subw rd rs1 rs2 31..25 = 32 14..12 = 0 6..2 = 0x0E 1..0 = 3

            instructionPayload.Funct3 = 0;

            // C.SUBW
            if (rvcPayload.CAMode == 0)
            {
                instructionPayload.Funct7 = 0x32;
            }

            instructionPayload.Rs1 = rvcPayload.Rs1;
            instructionPayload.Rs2 = rvcPayload.Rs2;
            instructionPayload.Rd  = rvcPayload.Rd;
        }
Exemple #24
0
        public void ParseSwSp(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            //
            // C.SWSP stores a 32-bit value in register rs2 to memory. It computes an effective address by
            // adding the zero - extended offset, scaled by 4, to the stack pointer, x2. It expands to sw rs2,
            // offset[7:2](x2).
            //
            // Immediate : [5] [4] [3] [2] [7] [6]

            Logger.Info("Parsing C.SWSP");

            instructionPayload.Funct3 = 2;
            instructionPayload.Rs2    = rvcPayload.Rs2; // The source
            instructionPayload.Rs1    = 2;              // The register pointing to the memory address

            int immediate = DecodeLoadStoreSp(rvcPayload.Immediate);

            instructionPayload.SignedImmediate = immediate;
        }
Exemple #25
0
        public void ParseSrai(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.SRAI is defined analogously to C.SRLI, but instead performs an arithmetic right shift. C.SRAI
            // expands to srai rd ′, rd ′, shamt[5:0].
            //

            // srai rd rs1 31..26 = 16 shamt 14..12 = 5 6..2 = 0x04 1..0 = 3
            Logger.Info("Parsing C.SRAI");

            if ((payload.Immediate & 0x20) == 0x20)
            {
                throw new RvcFormatException("Bit 5 for the RV32C C.SRAI must be zero");
            }

            instructionPayload.Funct3          = 5;
            instructionPayload.Rs1             = payload.Rs1;
            instructionPayload.Rd              = payload.Rd;
            instructionPayload.SignedImmediate = payload.Immediate | 0x400;
        }
Exemple #26
0
        public void ParseLwSp(RvcPayload rvcPayload, InstructionPayload instructionPayload)
        {
            //
            // C.LWSP loads a 32-bit value from memory into register rd. It computes an effective address
            // by adding the zero-extended offset, scaled by 4, to the stack pointer, x2. It expands to lw rd,
            // offset[7:2](x2).C.LWSP is only valid when rd̸ = x0; the code points with rd = x0 are reserved.
            //
            // 15...13     12      11..7     6 ... 2         1..0
            // C.LWSP   offset[5] dest̸=0   offset[4:2|7:6]   C2
            //
            // Immediate :  [5] [4] [3] [2] [7] [6]

            Logger.Info("Parsing C.LWSP");

            instructionPayload.Rd     = rvcPayload.Rd;
            instructionPayload.Funct3 = 2;
            instructionPayload.Rs1    = 2;

            int immediate = DecodeLoadStoreSp(rvcPayload.Immediate);

            instructionPayload.SignedImmediate = immediate;
        }
Exemple #27
0
        public void ParseLi(RvcPayload payload, InstructionPayload instructionPayload)
        {
            //
            // C.LI loads the sign-extended 6-bit immediate, imm, into register rd. C.LI expands into addi rd,
            // x0, imm[5:0].C.LI is only valid when rd̸ = x0; the code points with rd = x0 encode HINTs.
            //

            // rd = Signed Bit/5  4 3 2 1 0

            // TODO: rd == 0 -> Hint... how?
            // for now:  throw an error with an indicatatio that the C.LI hint mode is not supported

            // ---> MathHelper...

            Logger.Info("Parsing C.LI");

            if (payload.Rd == 0)
            {
                throw new RvcFormatException("C.LI using hint mode (rd=0) is currently not supported");
            }

            instructionPayload.Rd = payload.Rd;

            // bit 4 3 2 1 0
            int buffer          = payload.Immediate;
            int signedImmediate = buffer & 0x1F;

            // signed bit 5
            buffer >>= 5;
            var b5 = buffer & 0x01;

            b5 <<= 5;

            signedImmediate |= b5;
            instructionPayload.SignedImmediate = MathHelper.GetSignedInteger(signedImmediate, 5);
        }
Exemple #28
0
        private InstructionPayload DecodeTypeR(Instruction instruction, IEnumerable <byte> inst32Coding)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            var  payload = new InstructionPayload(instruction, inst32Coding);
            var  bytes   = inst32Coding;
            uint workingBuffer;

            // b4   (bit 0...7)
            // b3   (bit 8...15)
            // b2   (bit 16...23)
            // b1   (bit 24...31)
            //
            // Opcode   = 0  ... 6
            // rd       = 7  ... 11
            // funct3   = 12 ... 14
            // rs1      = 15 ... 19
            // rs2      = 20 ... 24
            // funct7   = 25 ... 31

            var b4 = bytes.ElementAt(3);
            var b3 = bytes.ElementAt(2);
            var b2 = bytes.ElementAt(1);

            // decode funct3
            workingBuffer   = b2;
            workingBuffer >>= 4;
            int funct3 = Convert.ToInt32(workingBuffer & 0x7);

            // decode rs1
            workingBuffer   = b3;
            workingBuffer <<= 8;
            workingBuffer  |= b2;
            //  working Buffer = b3b2;
            workingBuffer >>= 7;
            workingBuffer  &= 0x1F;
            int rs1 = Convert.ToInt32(workingBuffer);

            // decode rs2
            workingBuffer   = b4;
            workingBuffer <<= 8;
            workingBuffer  |= b3;
            workingBuffer >>= 4;
            workingBuffer  &= 0x1F;
            int rs2 = Convert.ToInt32(workingBuffer);

            // funct 7
            workingBuffer   = b4;
            workingBuffer >>= 1;
            workingBuffer  &= 0x7F;
            int funct7 = Convert.ToInt32(workingBuffer);

            var rd = GetRd(inst32Coding);

            payload.Rd     = rd;
            payload.Funct3 = funct3;
            payload.Rs1    = rs1;
            payload.Rs2    = rs2;
            payload.Funct7 = funct7;
            return(payload);
        }
Exemple #29
0
        private InstructionPayload DecodeTypeJ(Instruction instruction, IEnumerable <byte> inst32Coding)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            var payload = new InstructionPayload(instruction, inst32Coding);
            var bytes   = inst32Coding;
            int workingBuffer;

            var b4 = bytes.ElementAt(3);
            var b3 = bytes.ElementAt(2);
            var b2 = bytes.ElementAt(1);

            // fill the buffer with b4 b3 b2
            workingBuffer   = b4;
            workingBuffer <<= 8;
            workingBuffer  |= b3;
            workingBuffer <<= 8;
            workingBuffer  |= b2;

            //
            // Always a multiplier of 2  => first bit = 0.
            //
            // Imm 1...10 : 21...30
            // Imm     11 : 20
            // Imm 12..19 : 12 ... 19
            // Imm     20 : Signed Bit
            //

            // Right shift and remove the rd bytes
            workingBuffer >>= 4;

            var rd = GetRd(inst32Coding);

            // Ready. Now extract the pieces of the immediate

            // Immm[19...12]
            int immediate = workingBuffer & 0xFF;

            immediate <<= 12;

            // Imm[11]
            workingBuffer >>= 8;
            int b11 = workingBuffer & 0x01;

            b11      <<= 11;
            immediate |= b11;

            // Imm[10...1]
            workingBuffer >>= 1;
            int b10to1 = workingBuffer & 0x3FF;

            b10to1   <<= 1;
            immediate |= b10to1;

            // Imm[20]
            workingBuffer >>= 10;
            int b20 = workingBuffer & 0x01;

            b20      <<= 20;
            immediate |= b20;

            //// shift by left for guaranteeing that we have 2 byte multiplier
            //immediate <<= 1;



            payload.Rd = rd;
            payload.SignedImmediate = MathHelper.GetSignedInteger(immediate, instruction.Type);
            return(payload);
        }
Exemple #30
0
        private InstructionPayload DecodeTypeB(Instruction instruction, IEnumerable <byte> inst32Coding)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            var payload = new InstructionPayload(instruction, inst32Coding);
            var bytes   = inst32Coding;
            int workingBuffer;

            // b4   (bit 0...7)
            // b3   (bit 8...15)
            // b2   (bit 16...23)
            // b1   (bit 24...31)
            //
            // Opcode   = 0  ... 6
            // rd       = 7  ... 11
            // funct3   = 12 ... 14
            // rs1      = 15 ... 19
            // rs2      = 20 ... 24
            // funct7   = 25 ... 31

            var b4 = bytes.ElementAt(3);
            var b3 = bytes.ElementAt(2);
            var b2 = bytes.ElementAt(1);
            var b1 = bytes.ElementAt(0);

            // decode funct3
            workingBuffer   = b2;
            workingBuffer >>= 4;
            int funct3 = Convert.ToInt32(workingBuffer & 0x7);

            // decode rs1
            workingBuffer   = b3;
            workingBuffer <<= 8;
            workingBuffer  |= b2;
            //  working Buffer = b3b2;
            workingBuffer >>= 7;
            workingBuffer  &= 0x1F;
            int rs1 = Convert.ToInt32(workingBuffer);

            // decode rs2
            workingBuffer   = b4;
            workingBuffer <<= 8;
            workingBuffer  |= b3;
            workingBuffer >>= 4;
            workingBuffer  &= 0x1F;
            int rs2 = Convert.ToInt32(workingBuffer);

            // compute the 12 bit signed integer
            int immediate;


            //
            // Read Imm[4...1]
            //
            workingBuffer   = b2;
            workingBuffer <<= 8;
            workingBuffer  |= b1;
            workingBuffer >>= 8; // Right shift the opcode and imm[11]
            immediate       = workingBuffer & 0x0F;

            //
            // Read Imm [10...5]
            //
            workingBuffer   = b4;
            workingBuffer >>= 1;
            workingBuffer  &= 0x7F;
            workingBuffer <<= 4;
            immediate      |= workingBuffer;

            //
            // Read Imm [11]
            //
            workingBuffer   = b1;
            workingBuffer >>= 7;
            workingBuffer <<= 10;
            immediate      |= workingBuffer;

            //
            //  Read Imm[12]
            //
            workingBuffer   = b4;
            workingBuffer >>= 7;
            workingBuffer <<= 11;
            immediate      |= workingBuffer;

            // Finally a left shift to the immediate for making sure it is based on a multiple of 2.
            // All in all a 12 Bit Signed Int
            immediate <<= 1;

            payload.Funct3          = funct3;
            payload.Rs1             = rs1;
            payload.Rs2             = rs2;
            payload.SignedImmediate = MathHelper.GetSignedInteger(immediate, InstructionType.B_Type);
            return(payload);
        }