|  |  |  | @@ -215,7 +215,7 @@ private: | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     /* start generated code */ | 
		
	
		
			
				|  |  |  |  |     const InstructionDesriptor instr_descr[75] = { | 
		
	
		
			
				|  |  |  |  |     const InstructionDesriptor instr_descr[86] = { | 
		
	
		
			
				|  |  |  |  |         /* entries are: valid value, valid mask, function ptr */ | 
		
	
		
			
				|  |  |  |  |         /* instruction LWU */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, | 
		
	
	
		
			
				
					
					|  |  |  | @@ -223,12 +223,6 @@ private: | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SD */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SLLI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SRLI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SRAI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai}, | 
		
	
		
			
				|  |  |  |  |         /* instruction ADDIW */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SLLIW */ | 
		
	
	
		
			
				
					
					|  |  |  | @@ -295,6 +289,12 @@ private: | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori}, | 
		
	
		
			
				|  |  |  |  |         /* instruction ANDI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SLLI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SRLI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SRAI */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai}, | 
		
	
		
			
				|  |  |  |  |         /* instruction ADD */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SUB */ | 
		
	
	
		
			
				
					
					|  |  |  | @@ -367,6 +367,28 @@ private: | 
		
	
		
			
				|  |  |  |  |         {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOMAXU.D */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d}, | 
		
	
		
			
				|  |  |  |  |         /* instruction LR.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction SC.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOSWAP.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOADD.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOXOR.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOAND.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOOR.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOMIN.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOMAX.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOMINU.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, | 
		
	
		
			
				|  |  |  |  |         /* instruction AMOMAXU.W */ | 
		
	
		
			
				|  |  |  |  |         {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |     // instruction LWU | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __lwu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
	
		
			
				
					
					|  |  |  | @@ -483,111 +505,6 @@ private: | 
		
	
		
			
				|  |  |  |  |         return std::make_tuple(vm::CONT, bb); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     // instruction SLLI | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SLLI"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_shamt_val = 0 | (bit_sub<20,6>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SLLI x%1$d, x%2$d, %3%"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->builder->CreateShl( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, fld_shamt_val)); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 SRLI | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SRLI"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_shamt_val = 0 | (bit_sub<20,6>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SRLI x%1$d, x%2$d, %3%"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->builder->CreateLShr( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, fld_shamt_val)); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 SRAI | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SRAI"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_shamt_val = 0 | (bit_sub<20,6>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SRAI x%1$d, x%2$d, %3%"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->builder->CreateAShr( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, fld_shamt_val)); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 ADDIW | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __addiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("ADDIW"); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1113,19 +1030,43 @@ private: | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* new_pc_val = this->builder->CreateAdd( | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |             this->gen_const(64U, fld_imm_val)); | 
		
	
		
			
				|  |  |  |  |         Value* align_val = this->builder->CreateAnd( | 
		
	
		
			
				|  |  |  |  |             new_pc_val, | 
		
	
		
			
				|  |  |  |  |             this->gen_const(64U, 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(64U, 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( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(traits<ARCH>::PC, 0), | 
		
	
		
			
				|  |  |  |  |                     this->gen_reg_load(traits<ARCH>::PC, 1), | 
		
	
		
			
				|  |  |  |  |                     this->gen_const(64U, 4)); | 
		
	
		
			
				|  |  |  |  |                 this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         Value* ret_val = this->builder->CreateAdd( | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |             this->gen_const(64U, fld_imm_val)); | 
		
	
		
			
				|  |  |  |  |             Value* PC_val = this->builder->CreateAnd( | 
		
	
		
			
				|  |  |  |  |             ret_val, | 
		
	
		
			
				|  |  |  |  |                 new_pc_val, | 
		
	
		
			
				|  |  |  |  |                 this->builder->CreateNot(this->gen_const(64U, 1))); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->builder->CreateBr(bbnext); | 
		
	
		
			
				|  |  |  |  |         bb=bbnext; | 
		
	
		
			
				|  |  |  |  |         this->builder->SetInsertPoint(bb); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         this->gen_trap_check(this->leave_blk); | 
		
	
		
			
				|  |  |  |  |         return std::make_tuple(iss::vm::BRANCH, nullptr); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1914,6 +1855,111 @@ private: | 
		
	
		
			
				|  |  |  |  |         return std::make_tuple(vm::CONT, bb); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     // instruction SLLI | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SLLI"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SLLI x%1$d, x%2$d, %3%"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->builder->CreateShl( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, fld_shamt_val)); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 SRLI | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SRLI"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SRLI x%1$d, x%2$d, %3%"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->builder->CreateLShr( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, fld_shamt_val)); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 SRAI | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SRAI"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SRAI x%1$d, x%2$d, %3%"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->builder->CreateAShr( | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs1_val, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, fld_shamt_val)); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 ADD | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("ADD"); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -3374,22 +3420,600 @@ private: | 
		
	
		
			
				|  |  |  |  |         return std::make_tuple(vm::CONT, bb); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     // instruction LR.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("LR.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("LR.W x%1$d, x%2$d"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                 this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |                 64, | 
		
	
		
			
				|  |  |  |  |                 true); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |             Value* RES_offs_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                 this->builder->CreateNeg(this->gen_const(8U, 1)), | 
		
	
		
			
				|  |  |  |  |                 32, | 
		
	
		
			
				|  |  |  |  |                 true); | 
		
	
		
			
				|  |  |  |  |             this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |                 traits<ARCH>::RES, | 
		
	
		
			
				|  |  |  |  |                 offs_val, | 
		
	
		
			
				|  |  |  |  |                 this->builder->CreateZExtOrTrunc(RES_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 SC.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("SC.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("SC.W x%1$d, x%2$d, x%3$d"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_read_mem(traits<ARCH>::RES, offs_val, 32/8); | 
		
	
		
			
				|  |  |  |  |         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); | 
		
	
		
			
				|  |  |  |  |         // this->builder->SetInsertPoint(bb); | 
		
	
		
			
				|  |  |  |  |         this->gen_cond_branch(this->builder->CreateICmp( | 
		
	
		
			
				|  |  |  |  |             ICmpInst::ICMP_NE, | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             this->gen_const(32U, 0)), | 
		
	
		
			
				|  |  |  |  |             bb_then, | 
		
	
		
			
				|  |  |  |  |             bbnext); | 
		
	
		
			
				|  |  |  |  |         this->builder->SetInsertPoint(bb_then); | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 1); | 
		
	
		
			
				|  |  |  |  |             this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |                 traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |                 offs_val, | 
		
	
		
			
				|  |  |  |  |                 this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->builder->CreateBr(bbnext); | 
		
	
		
			
				|  |  |  |  |         bb=bbnext; | 
		
	
		
			
				|  |  |  |  |         this->builder->SetInsertPoint(bb); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->gen_choose( | 
		
	
		
			
				|  |  |  |  |                 this->builder->CreateICmp( | 
		
	
		
			
				|  |  |  |  |                     ICmpInst::ICMP_NE, | 
		
	
		
			
				|  |  |  |  |                     res1_val, | 
		
	
		
			
				|  |  |  |  |                     this->gen_const(64U, 0)), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, 0), | 
		
	
		
			
				|  |  |  |  |                 this->gen_const(64U, 1), | 
		
	
		
			
				|  |  |  |  |                 64); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOSWAP.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOSWAP.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOSWAP.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                 this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |                 64, | 
		
	
		
			
				|  |  |  |  |                 true); | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOADD.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOADD.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOADD.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             true); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->builder->CreateAdd( | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0)); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOXOR.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOXOR.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOXOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             true); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->builder->CreateXor( | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0)); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOAND.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOAND.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOAND.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             true); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->builder->CreateAnd( | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0)); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOOR.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOOR.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             true); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->builder->CreateOr( | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0)); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOMIN.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOMIN.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOMIN.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             true); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->gen_choose( | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateICmp( | 
		
	
		
			
				|  |  |  |  |                 ICmpInst::ICMP_SGT, | 
		
	
		
			
				|  |  |  |  |                 this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                     res1_val, | 
		
	
		
			
				|  |  |  |  |                     64, true), | 
		
	
		
			
				|  |  |  |  |                 this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                     this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |                     64, true)), | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             64); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOMAX.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOMAX.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOMAX.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             true); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->gen_choose( | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateICmp( | 
		
	
		
			
				|  |  |  |  |                 ICmpInst::ICMP_SLT, | 
		
	
		
			
				|  |  |  |  |                 this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                     res1_val, | 
		
	
		
			
				|  |  |  |  |                     64, true), | 
		
	
		
			
				|  |  |  |  |                 this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                     this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |                     64, true)), | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             64); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOMINU.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOMINU.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOMINU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             false); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->gen_choose( | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateICmp( | 
		
	
		
			
				|  |  |  |  |                 ICmpInst::ICMP_UGT, | 
		
	
		
			
				|  |  |  |  |                 res1_val, | 
		
	
		
			
				|  |  |  |  |                 this->gen_reg_load(fld_rs2_val, 0)), | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             64); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 AMOMAXU.W | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock*> __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | 
		
	
		
			
				|  |  |  |  |         bb->setName("AMOMAXU.W"); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("AMOMAXU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc=pc+4; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); | 
		
	
		
			
				|  |  |  |  |         Value* res1_val = this->gen_ext( | 
		
	
		
			
				|  |  |  |  |             this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8), | 
		
	
		
			
				|  |  |  |  |             64, | 
		
	
		
			
				|  |  |  |  |             false); | 
		
	
		
			
				|  |  |  |  |         if(fld_rd_val != 0){ | 
		
	
		
			
				|  |  |  |  |             Value* X_rd_val = res1_val; | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Value* res2_val = this->gen_choose( | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateICmp( | 
		
	
		
			
				|  |  |  |  |                 ICmpInst::ICMP_ULT, | 
		
	
		
			
				|  |  |  |  |                 this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                     res1_val, | 
		
	
		
			
				|  |  |  |  |                     64, false), | 
		
	
		
			
				|  |  |  |  |                 this->gen_ext( | 
		
	
		
			
				|  |  |  |  |                     this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |                     64, false)), | 
		
	
		
			
				|  |  |  |  |             this->gen_reg_load(fld_rs2_val, 0), | 
		
	
		
			
				|  |  |  |  |             res1_val, | 
		
	
		
			
				|  |  |  |  |             64); | 
		
	
		
			
				|  |  |  |  |         Value* MEM_offs_val = res2_val; | 
		
	
		
			
				|  |  |  |  |         this->gen_write_mem( | 
		
	
		
			
				|  |  |  |  |             traits<ARCH>::MEM, | 
		
	
		
			
				|  |  |  |  |             offs_val, | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | 
		
	
		
			
				|  |  |  |  |         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         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 generated code  */ | 
		
	
		
			
				|  |  |  |  |     /**************************************************************************** | 
		
	
		
			
				|  |  |  |  |      * end opcode definitions | 
		
	
		
			
				|  |  |  |  |      ****************************************************************************/ | 
		
	
		
			
				|  |  |  |  |     std::tuple<vm::continuation_e, llvm::BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, | 
		
	
		
			
				|  |  |  |  |                                                                           llvm::BasicBlock *bb) { | 
		
	
		
			
				|  |  |  |  |         // this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |         this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true), | 
		
	
		
			
				|  |  |  |  |                                    get_reg_ptr(traits<ARCH>::PC), true); | 
		
	
		
			
				|  |  |  |  |         this->builder->CreateStore( | 
		
	
		
			
				|  |  |  |  |             this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true), | 
		
	
		
			
				|  |  |  |  |                                      this->gen_const(64U, 1)), | 
		
	
		
			
				|  |  |  |  |             get_reg_ptr(traits<ARCH>::ICOUNT), true); | 
		
	
		
			
				|  |  |  |  |         if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |         bb->setName("illegal_instruction"); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::PRE_SYNC); | 
		
	
		
			
				|  |  |  |  |         if(this->disass_enabled){ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             /* generate console output when executing the command */ | 
		
	
		
			
				|  |  |  |  |             boost::format ins_fmter("DB 0x%1$x"); | 
		
	
		
			
				|  |  |  |  |             ins_fmter % (uint64_t)instr; | 
		
	
		
			
				|  |  |  |  |             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); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         pc = pc + ((instr & 3) == 3 ? 4 : 2); | 
		
	
		
			
				|  |  |  |  |         this->gen_raise_trap(0, 2);     // illegal instruction trap | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         this->gen_raise_trap(0, 2); | 
		
	
		
			
				|  |  |  |  |         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | 
		
	
		
			
				|  |  |  |  |         this->gen_trap_check(this->leave_blk); | 
		
	
		
			
				|  |  |  |  |         return std::make_tuple(iss::vm::BRANCH, nullptr); | 
		
	
	
		
			
				
					
					|  |  |  |   |