void arch_decode_bit(Value *flags, Value *bit, int shift, int width, BasicBlock *bb) { Value *n = BinaryOperator::Create(Instruction::LShr, flags, ConstantInt::get(getIntegerType(width), shift), "", bb); n = new TruncInst(n, getIntegerType(1), "", bb); new StoreInst(n, bit, bb); }
Value * arch_encode_bit(Value *flags, Value *bit, int shift, int width, BasicBlock *bb) { Value *n = new LoadInst(bit, "", false, bb); bit = new ZExtInst(n, getIntegerType(width), "", bb); bit = BinaryOperator::Create(Instruction::Shl, bit, ConstantInt::get(getIntegerType(width), shift), "", bb); return BinaryOperator::Create(Instruction::Or, flags, bit, "", bb); }
static Value * arch_6502_get_operand_lvalue(cpu_t *cpu, addr_t pc, BasicBlock* bb) { int am = get_addmode(cpu->RAM[pc]); Value *index_register_before; Value *index_register_after; bool is_indirect; bool is_8bit_base; switch (am) { case ADDMODE_ACC: return ptr_A; case ADDMODE_BRA: case ADDMODE_IMPL: return NULL; case ADDMODE_IMM: { Value *ptr_temp = new AllocaInst(getIntegerType(8), "temp", bb); new StoreInst(CONST8(OPERAND_8), ptr_temp, bb); return ptr_temp; } } is_indirect = ((am == ADDMODE_IND) || (am == ADDMODE_INDX) || (am == ADDMODE_INDY)); is_8bit_base = !((am == ADDMODE_ABS) || (am == ADDMODE_ABSX) || (am == ADDMODE_ABSY)); index_register_before = NULL; if ((am == ADDMODE_ABSX) || (am == ADDMODE_INDX) || (am == ADDMODE_ZPX)) index_register_before = ptr_X; if ((am == ADDMODE_ABSY) || (am == ADDMODE_ZPY)) index_register_before = ptr_Y; index_register_after = (am == ADDMODE_INDY)? ptr_Y : NULL; #if 0 LOG("pc = %x\n", pc); LOG("index_register_before = %x\n", index_register_before); LOG("index_register_after = %x\n", index_register_after); LOG("is_indirect = %x\n", is_indirect); LOG("is_8bit_base = %x\n", is_8bit_base); #endif /* create base constant */ uint16_t base = is_8bit_base? (OPERAND_8):(OPERAND_16); Value *ea = CONST32(base); if (index_register_before) ea = ADD(ZEXT32(LOAD(index_register_before)), ea); /* wrap around in zero page */ if (is_8bit_base) ea = AND(ea, CONST32(0x00FF)); else if (base >= 0xFF00) /* wrap around in memory */ ea = AND(ea, CONST32(0xFFFF)); if (is_indirect) ea = ZEXT32(LOAD_RAM16(ea)); if (index_register_after) ea = ADD(ZEXT32(LOAD(index_register_after)), ea); return GEP(ea); }
Value * arch_cttz(cpu_t *cpu, size_t width, Value *v, BasicBlock *bb) { Type const *ty = getIntegerType(width); return CallInst::Create(Intrinsic::getDeclaration(cpu->mod, Intrinsic::cttz, &ty, 1), v, "", bb); }
Value * arch_cttz(cpu_t *cpu, size_t width, Value *v, BasicBlock *bb) { std::vector<Type *> arg_type; arg_type.push_back(getIntegerType(width)); return CallInst::Create(Intrinsic::getDeclaration(cpu->mod, Intrinsic::cttz, arg_type), v, "", bb); }
BasicBlock * cpu_translate_all(cpu_t *cpu, BasicBlock *bb_ret, BasicBlock *bb_trap) { // find all instructions that need labels and create basic blocks for them int bbs = 0; addr_t pc; pc = cpu->code_start; while (pc < cpu->code_end) { // Do not create the basic block if it is already present in some other function. if (is_start_of_basicblock(cpu, pc) && !(get_tag(cpu, pc) & TAG_TRANSLATED)) { create_basicblock(cpu, pc, cpu->cur_func, BB_TYPE_NORMAL); bbs++; } pc++; } LOG("bbs: %d\n", bbs); // create dispatch basicblock BasicBlock* bb_dispatch = BasicBlock::Create(_CTX(), "dispatch", cpu->cur_func, 0); Value *v_pc = new LoadInst(cpu->ptr_PC, "", false, bb_dispatch); SwitchInst* sw = SwitchInst::Create(v_pc, bb_ret, bbs, bb_dispatch); // translate basic blocks bbaddr_map &bb_addr = cpu->func_bb[cpu->cur_func]; bbaddr_map::const_iterator it; for (it = bb_addr.begin(); it != bb_addr.end(); it++) { pc = it->first; BasicBlock *cur_bb = it->second; tag_t tag; BasicBlock *bb_target = NULL, *bb_next = NULL, *bb_cont = NULL; // Tag the function as translated. or_tag(cpu, pc, TAG_TRANSLATED); LOG("basicblock: L%08llx\n", (unsigned long long)pc); // Add dispatch switch case for basic block. ConstantInt* c = ConstantInt::get(getIntegerType(cpu->info.address_size), pc); sw->addCase(c, cur_bb); do { tag_t dummy1; if (LOGGING) disasm_instr(cpu, pc); tag = get_tag(cpu, pc); /* get address of the following instruction */ addr_t new_pc, next_pc; cpu->f.tag_instr(cpu, pc, &dummy1, &new_pc, &next_pc); /* get target basic block */ if (tag & TAG_RET) bb_target = bb_dispatch; if (tag & (TAG_CALL|TAG_BRANCH)) { if (new_pc == NEW_PC_NONE) /* translate_instr() will set PC */ bb_target = bb_dispatch; else bb_target = (BasicBlock*)lookup_basicblock(cpu, cpu->cur_func, new_pc, bb_ret, BB_TYPE_NORMAL); } /* get not-taken basic block */ if (tag & TAG_CONDITIONAL) bb_next = (BasicBlock*)lookup_basicblock(cpu, cpu->cur_func, next_pc, bb_ret, BB_TYPE_NORMAL); bb_cont = translate_instr(cpu, pc, tag, bb_target, bb_trap, bb_next, cur_bb); pc = next_pc; } while ( /* new basic block starts here (and we haven't translated it yet)*/ (!is_start_of_basicblock(cpu, pc)) && /* end of code section */ //XXX no: this is whether it's TAG_CODE is_code(cpu, pc) && /* last intruction jumped away */ bb_cont ); /* link with next basic block if there isn't a control flow instr. already */ if (bb_cont) { BasicBlock *target = (BasicBlock*)lookup_basicblock(cpu, cpu->cur_func, pc, bb_ret, BB_TYPE_NORMAL); LOG("info: linking continue $%04llx!\n", (unsigned long long)pc); BranchInst::Create(target, bb_cont); } } return bb_dispatch; }