Updated compressed instructions for RV32D
This commit is contained in:
		| @@ -218,9 +218,9 @@ InsructionSet RV32FC extends RV32IC{ | ||||
| 			val res[32] <= MEM[offs]{32}; | ||||
| 			if(FLEN==32) | ||||
| 				F[rd_idx] <= res; | ||||
| 			else { | ||||
| 				val upper[FLEN] <= (-1<<31); | ||||
| 				F[rd_idx] <= upper*2 | res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		}  | ||||
| 		C.FSW { | ||||
| @@ -239,9 +239,9 @@ InsructionSet RV32FC extends RV32IC{ | ||||
| 			val res[32] <= MEM[offs]{32}; | ||||
| 			if(FLEN==32) | ||||
| 				F[rd] <= res; | ||||
| 			else { | ||||
| 				val upper[FLEN] <= (-1<<31); | ||||
| 				F[rd] <= upper*2 | res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<32) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		C.FSWSP { | ||||
| @@ -249,7 +249,7 @@ InsructionSet RV32FC extends RV32IC{ | ||||
| 			args_disass:"f%rs2$d, %uimm%(x2), "; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			MEM[offs]{32}<=F[rs2]; | ||||
| 			MEM[offs]{32}<=F[rs2]{32}; | ||||
| 		}		 | ||||
| 	} | ||||
| } | ||||
| @@ -268,15 +268,45 @@ InsructionSet RV32DC extends RV32IC{ | ||||
| 	instructions{ | ||||
| 		C.FLD { //(RV32/64) | ||||
| 			encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; | ||||
| 			args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			val res[64] <= MEM[offs]{64}; | ||||
| 			if(FLEN==64) | ||||
| 				F[rd_idx] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd_idx] <= (upper<<64) | res; | ||||
| 			} | ||||
| 	 	} | ||||
| 		C.FSD { //(RV32/64) | ||||
| 			encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; | ||||
| 			args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val rs2_idx[5] <= rs2+8; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			MEM[offs]{64}<=F[rs2_idx]{64}; | ||||
| 		}  | ||||
| 		C.FLDSP {//(RV32/64) | ||||
| 			encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; | ||||
| 			args_disass:"f%rd$d, %uimm%(x2)"; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			val res[64] <= MEM[offs]{64}; | ||||
| 			if(FLEN==64) | ||||
| 				F[rd] <= res; | ||||
| 			else { // NaN boxing | ||||
| 				val upper[FLEN] <= -1; | ||||
| 				F[rd] <= (upper<<64) | zext(res, FLEN); | ||||
| 			} | ||||
| 		} | ||||
| 		C.FSDSP {//(RV32/64) | ||||
| 			encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; | ||||
| 			args_disass:"f%rs2$d, %uimm%(x2), "; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			val offs[XLEN] <= X[x2_idx]+uimm; | ||||
| 			MEM[offs]{64}<=F[rs2]{64}; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { | ||||
|     } | ||||
| } | ||||
|  | ||||
| Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D { | ||||
| Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32DC { | ||||
|     constants { | ||||
|         XLEN:=32; | ||||
|         FLEN:=64; | ||||
|   | ||||
| @@ -194,7 +194,7 @@ private: | ||||
|         compile_func op; | ||||
|     }; | ||||
|  | ||||
|     const std::array<InstructionDesriptor, 155> instr_descr = {{ | ||||
|     const std::array<InstructionDesriptor, 159> instr_descr = {{ | ||||
|          /* entries are: size, valid value, valid mask, function ptr */ | ||||
|         /* instruction LUI */ | ||||
|         {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, | ||||
| @@ -506,6 +506,14 @@ private: | ||||
|         {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, | ||||
|         /* instruction FCVT.D.WU */ | ||||
|         {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, | ||||
|         /* instruction C.FLD */ | ||||
|         {16, 0b0010000000000000, 0b1110000000000011, &this_class::__c_fld}, | ||||
|         /* instruction C.FSD */ | ||||
|         {16, 0b1010000000000000, 0b1110000000000011, &this_class::__c_fsd}, | ||||
|         /* instruction C.FLDSP */ | ||||
|         {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_fldsp}, | ||||
|         /* instruction C.FSDSP */ | ||||
|         {16, 0b1010000000000010, 0b1110000000000011, &this_class::__c_fsdsp}, | ||||
|     }}; | ||||
|   | ||||
|     /* instruction definitions */ | ||||
| @@ -641,43 +649,19 @@ private: | ||||
|     	Value* cur_pc_val = this->gen_const(32, pc.val); | ||||
|     	pc=pc+4; | ||||
|     	 | ||||
|     	Value* new_pc_val = this->builder.CreateAdd( | ||||
|     	if(fld_rd_val != 0){ | ||||
|     	    Value* X_rd_val = this->builder.CreateAdd( | ||||
|     	        cur_pc_val, | ||||
|     	        this->gen_const(32U, 4)); | ||||
|     	    this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::X0), false); | ||||
|     	} | ||||
|     	Value* ret_val = this->builder.CreateAdd( | ||||
|     	    this->gen_reg_load(fld_rs1_val + traits<ARCH>::X0, 0), | ||||
|     	    this->gen_const(32U, fld_imm_val)); | ||||
|     	Value* align_val = this->builder.CreateAnd( | ||||
|     	    new_pc_val, | ||||
|     	    this->gen_const(32U, 2)); | ||||
|     	llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); | ||||
|     	llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); | ||||
|     	llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); | ||||
|     	// this->builder.SetInsertPoint(bb); | ||||
|     	this->gen_cond_branch(this->builder.CreateICmp( | ||||
|     	    ICmpInst::ICMP_NE, | ||||
|     	    align_val, | ||||
|     	    this->gen_const(32U, 0)), | ||||
|     	    bb_then, | ||||
|     	    bb_else); | ||||
|     	this->builder.SetInsertPoint(bb_then); | ||||
|     	{ | ||||
|     	    this->gen_raise_trap(0, 0); | ||||
|     	} | ||||
|     	this->builder.CreateBr(bbnext); | ||||
|     	this->builder.SetInsertPoint(bb_else); | ||||
|     	{ | ||||
|     	    if(fld_rd_val != 0){ | ||||
|     	        Value* X_rd_val = this->builder.CreateAdd( | ||||
|     	            cur_pc_val, | ||||
|     	            this->gen_const(32U, 4)); | ||||
|     	        this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::X0), false); | ||||
|     	    } | ||||
|     	    Value* PC_val = this->builder.CreateAnd( | ||||
|     	        new_pc_val, | ||||
|     	        this->builder.CreateNot(this->gen_const(32U, 1))); | ||||
|     	    this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     	} | ||||
|     	this->builder.CreateBr(bbnext); | ||||
|     	bb=bbnext; | ||||
|     	this->builder.SetInsertPoint(bb); | ||||
|     	Value* PC_val = this->builder.CreateAnd( | ||||
|     	    ret_val, | ||||
|     	    this->builder.CreateNot(this->gen_const(32U, 1))); | ||||
|     	this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     	this->gen_sync(iss::POST_SYNC, 3); | ||||
|     	this->gen_trap_check(this->leave_blk); | ||||
|     	return std::make_tuple(iss::vm::BRANCH, nullptr); | ||||
| @@ -6368,13 +6352,16 @@ private: | ||||
|     	    Value* F_rd_idx_val = res_val; | ||||
|     	    this->builder.CreateStore(F_rd_idx_val, get_reg_ptr(rd_idx_val + traits<ARCH>::F0), false); | ||||
|     	} else { | ||||
|     	    uint64_t upper_val = (-1) << 31; | ||||
|     	    Value* F_rd_idx_val = this->builder.CreateOr( | ||||
|     	        this->builder.CreateMul( | ||||
|     	    uint64_t upper_val = (-1); | ||||
|     	    Value* F_rd_val = this->builder.CreateOr( | ||||
|     	        this->builder.CreateShl( | ||||
|     	            this->gen_const(64U, upper_val), | ||||
|     	            this->gen_const(64U, 2)), | ||||
|     	        res_val); | ||||
|     	    this->builder.CreateStore(F_rd_idx_val, get_reg_ptr(rd_idx_val + traits<ARCH>::F0), false); | ||||
|     	            this->gen_const(64U, 32)), | ||||
|     	        this->gen_ext( | ||||
|     	            res_val, | ||||
|     	            64, | ||||
|     	            false)); | ||||
|     	    this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::F0), false); | ||||
|     	} | ||||
|     	this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|     	this->gen_sync(iss::POST_SYNC, 125); | ||||
| @@ -6459,12 +6446,15 @@ private: | ||||
|     	    Value* F_rd_val = res_val; | ||||
|     	    this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::F0), false); | ||||
|     	} else { | ||||
|     	    uint64_t upper_val = (-1) << 31; | ||||
|     	    uint64_t upper_val = (-1); | ||||
|     	    Value* F_rd_val = this->builder.CreateOr( | ||||
|     	        this->builder.CreateMul( | ||||
|     	        this->builder.CreateShl( | ||||
|     	            this->gen_const(64U, upper_val), | ||||
|     	            this->gen_const(64U, 2)), | ||||
|     	        res_val); | ||||
|     	            this->gen_const(64U, 32)), | ||||
|     	        this->gen_ext( | ||||
|     	            res_val, | ||||
|     	            64, | ||||
|     	            false)); | ||||
|     	    this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::F0), false); | ||||
|     	} | ||||
|     	this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
| @@ -6501,7 +6491,10 @@ private: | ||||
|     	Value* offs_val = this->builder.CreateAdd( | ||||
|     	    this->gen_reg_load(x2_idx_val + traits<ARCH>::X0, 0), | ||||
|     	    this->gen_const(32U, fld_uimm_val)); | ||||
|     	Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val + traits<ARCH>::F0, 0); | ||||
|     	Value* MEM_offs_val = this->builder.CreateTrunc( | ||||
|     	    this->gen_reg_load(fld_rs2_val + traits<ARCH>::F0, 0), | ||||
|     	    this-> get_type(32)  | ||||
|     	); | ||||
|     	this->gen_write_mem( | ||||
|     	    traits<ARCH>::MEM, | ||||
|     	    offs_val, | ||||
| @@ -8096,6 +8089,191 @@ private: | ||||
|     	return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     /* instruction 155: C.FLD */ | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_fld(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|     	bb->setName("C.FLD"); | ||||
|     	 | ||||
|     	this->gen_sync(iss::PRE_SYNC, 155); | ||||
|     	 | ||||
|     	uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); | ||||
|     	uint8_t fld_uimm_val = 0 | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3); | ||||
|     	uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); | ||||
|     	if(this->disass_enabled){ | ||||
|     	    /* generate console output when executing the command */ | ||||
|     	    boost::format ins_fmter("C.FLD f(8+%1$d), %2%(x(8+%3$d))"); | ||||
|     	    ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; | ||||
|     	    std::vector<llvm::Value*> args { | ||||
|     	        this->core_ptr, | ||||
|     	        this->gen_const(64, pc.val), | ||||
|     	        this->builder.CreateGlobalStringPtr(ins_fmter.str()), | ||||
|     	    }; | ||||
|     	    this->builder.CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|     	} | ||||
|     	 | ||||
|     	Value* cur_pc_val = this->gen_const(32, pc.val); | ||||
|     	pc=pc+2; | ||||
|     	 | ||||
|     	uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|     	uint8_t rd_idx_val = (fld_rd_val + 8); | ||||
|     	Value* offs_val = this->builder.CreateAdd( | ||||
|     	    this->gen_reg_load(rs1_idx_val + traits<ARCH>::X0, 0), | ||||
|     	    this->gen_const(32U, fld_uimm_val)); | ||||
|     	Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8); | ||||
|     	if(64 == 64){ | ||||
|     	    Value* F_rd_idx_val = res_val; | ||||
|     	    this->builder.CreateStore(F_rd_idx_val, get_reg_ptr(rd_idx_val + traits<ARCH>::F0), false); | ||||
|     	} else { | ||||
|     	    uint64_t upper_val = (-1); | ||||
|     	    Value* F_rd_idx_val = this->builder.CreateOr( | ||||
|     	        this->builder.CreateShl( | ||||
|     	            this->gen_const(64U, upper_val), | ||||
|     	            this->gen_const(64U, 64)), | ||||
|     	        res_val); | ||||
|     	    this->builder.CreateStore(F_rd_idx_val, get_reg_ptr(rd_idx_val + traits<ARCH>::F0), false); | ||||
|     	} | ||||
|     	this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|     	this->gen_sync(iss::POST_SYNC, 155); | ||||
|     	bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|     	this->gen_trap_check(bb); | ||||
|     	return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     /* instruction 156: C.FSD */ | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_fsd(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|     	bb->setName("C.FSD"); | ||||
|     	 | ||||
|     	this->gen_sync(iss::PRE_SYNC, 156); | ||||
|     	 | ||||
|     	uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); | ||||
|     	uint8_t fld_uimm_val = 0 | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3); | ||||
|     	uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); | ||||
|     	if(this->disass_enabled){ | ||||
|     	    /* generate console output when executing the command */ | ||||
|     	    boost::format ins_fmter("C.FSD f(8+%1$d), %2%(x(8+%3$d))"); | ||||
|     	    ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; | ||||
|     	    std::vector<llvm::Value*> args { | ||||
|     	        this->core_ptr, | ||||
|     	        this->gen_const(64, pc.val), | ||||
|     	        this->builder.CreateGlobalStringPtr(ins_fmter.str()), | ||||
|     	    }; | ||||
|     	    this->builder.CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|     	} | ||||
|     	 | ||||
|     	Value* cur_pc_val = this->gen_const(32, pc.val); | ||||
|     	pc=pc+2; | ||||
|     	 | ||||
|     	uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|     	uint8_t rs2_idx_val = (fld_rs2_val + 8); | ||||
|     	Value* offs_val = this->builder.CreateAdd( | ||||
|     	    this->gen_reg_load(rs1_idx_val + traits<ARCH>::X0, 0), | ||||
|     	    this->gen_const(32U, fld_uimm_val)); | ||||
|     	Value* MEM_offs_val = this->builder.CreateTrunc( | ||||
|     	    this->gen_reg_load(rs2_idx_val + traits<ARCH>::F0, 0), | ||||
|     	    this-> get_type(64)  | ||||
|     	); | ||||
|     	this->gen_write_mem( | ||||
|     	    traits<ARCH>::MEM, | ||||
|     	    offs_val, | ||||
|     	    this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); | ||||
|     	this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|     	this->gen_sync(iss::POST_SYNC, 156); | ||||
|     	bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|     	this->gen_trap_check(bb); | ||||
|     	return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     /* instruction 157: C.FLDSP */ | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_fldsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|     	bb->setName("C.FLDSP"); | ||||
|     	 | ||||
|     	this->gen_sync(iss::PRE_SYNC, 157); | ||||
|     	 | ||||
|     	uint16_t fld_uimm_val = 0 | (bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5); | ||||
|     	uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | ||||
|     	if(this->disass_enabled){ | ||||
|     	    /* generate console output when executing the command */ | ||||
|     	    boost::format ins_fmter("C.FLDSP f%1$d, %2%(x2)"); | ||||
|     	    ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val; | ||||
|     	    std::vector<llvm::Value*> args { | ||||
|     	        this->core_ptr, | ||||
|     	        this->gen_const(64, pc.val), | ||||
|     	        this->builder.CreateGlobalStringPtr(ins_fmter.str()), | ||||
|     	    }; | ||||
|     	    this->builder.CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|     	} | ||||
|     	 | ||||
|     	Value* cur_pc_val = this->gen_const(32, pc.val); | ||||
|     	pc=pc+2; | ||||
|     	 | ||||
|     	uint8_t x2_idx_val = 2; | ||||
|     	Value* offs_val = this->builder.CreateAdd( | ||||
|     	    this->gen_reg_load(x2_idx_val + traits<ARCH>::X0, 0), | ||||
|     	    this->gen_const(32U, fld_uimm_val)); | ||||
|     	Value* res_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 64/8); | ||||
|     	if(64 == 64){ | ||||
|     	    Value* F_rd_val = res_val; | ||||
|     	    this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::F0), false); | ||||
|     	} else { | ||||
|     	    uint64_t upper_val = (-1); | ||||
|     	    Value* F_rd_val = this->builder.CreateOr( | ||||
|     	        this->builder.CreateShl( | ||||
|     	            this->gen_const(64U, upper_val), | ||||
|     	            this->gen_const(64U, 64)), | ||||
|     	        this->gen_ext( | ||||
|     	            res_val, | ||||
|     	            64, | ||||
|     	            false)); | ||||
|     	    this->builder.CreateStore(F_rd_val, get_reg_ptr(fld_rd_val + traits<ARCH>::F0), false); | ||||
|     	} | ||||
|     	this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|     	this->gen_sync(iss::POST_SYNC, 157); | ||||
|     	bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|     	this->gen_trap_check(bb); | ||||
|     	return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     /* instruction 158: C.FSDSP */ | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_fsdsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|     	bb->setName("C.FSDSP"); | ||||
|     	 | ||||
|     	this->gen_sync(iss::PRE_SYNC, 158); | ||||
|     	 | ||||
|     	uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); | ||||
|     	uint16_t fld_uimm_val = 0 | (bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3); | ||||
|     	if(this->disass_enabled){ | ||||
|     	    /* generate console output when executing the command */ | ||||
|     	    boost::format ins_fmter("C.FSDSP f%1$d, %2%(x2), "); | ||||
|     	    ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val; | ||||
|     	    std::vector<llvm::Value*> args { | ||||
|     	        this->core_ptr, | ||||
|     	        this->gen_const(64, pc.val), | ||||
|     	        this->builder.CreateGlobalStringPtr(ins_fmter.str()), | ||||
|     	    }; | ||||
|     	    this->builder.CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|     	} | ||||
|     	 | ||||
|     	Value* cur_pc_val = this->gen_const(32, pc.val); | ||||
|     	pc=pc+2; | ||||
|     	 | ||||
|     	uint8_t x2_idx_val = 2; | ||||
|     	Value* offs_val = this->builder.CreateAdd( | ||||
|     	    this->gen_reg_load(x2_idx_val + traits<ARCH>::X0, 0), | ||||
|     	    this->gen_const(32U, fld_uimm_val)); | ||||
|     	Value* MEM_offs_val = this->builder.CreateTrunc( | ||||
|     	    this->gen_reg_load(fld_rs2_val + traits<ARCH>::F0, 0), | ||||
|     	    this-> get_type(64)  | ||||
|     	); | ||||
|     	this->gen_write_mem( | ||||
|     	    traits<ARCH>::MEM, | ||||
|     	    offs_val, | ||||
|     	    this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); | ||||
|     	this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|     	this->gen_sync(iss::POST_SYNC, 158); | ||||
|     	bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|     	this->gen_trap_check(bb); | ||||
|     	return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     /**************************************************************************** | ||||
|      * end opcode definitions | ||||
|      ****************************************************************************/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user