예제 #1
0
unsigned long MemoryForCpu::read8_se(unsigned long addr)
{
	unsigned char c;

	if(port->read8(addr, &c))
		return signExtend8(c);
	if(ifont->read8(addr, &c))
		return signExtend8(c);
	if(rommmp->read8(addr, &c))
		return signExtend8(c);

	return signExtend8(readMemory8(addr));
}
예제 #2
0
bool Instruction::exec() {
	//
	// NOTE: Assumes pc has been pre-incremented
	// Important for branch instruction operation
	//
	uint64_t p;  // product for mult, div
	bool keepGoing = true;
	pc += 4;
	switch(token) {
		case SLL:
			reg[rd] = reg[rt] << shamt;
			break;
		case SRL:
			reg[rd] = reg[rt] >> shamt;
			break;
		case SRA:
			reg[rd] = (int) reg[rt] >> shamt;
			break;
		case SLLV:
			reg[rd] = reg[rt] << reg[rs];
			break;
		case SRLV:
			reg[rd] = reg[rt] >> reg[rs];
			break;
		case SRAV:
			reg[rd] = (int) reg[rt] >> reg[rs];
			break;
		case ADD:
			reg[rd] = reg[rs] + reg[rt];
			break;
		case ADDU:
			reg[rd] = reg[rs] + reg[rt];
			break;
		case SUB:
			reg[rd] = reg[rs] - reg[rt];
			break;
		case SUBU:
			reg[rd] = reg[rs] - reg[rt];
			break;
		case AND:
			reg[rd] = reg[rs] & reg[rt];
			break;
		case OR:
			reg[rd] = reg[rs] | reg[rt];
			break;
		case XOR:
			reg[rd] = reg[rs] ^ reg[rt];
			break;
		case NOR:
			reg[rd] = ~(reg[rs] | reg[rt]);
			break;
		case MULT:
			p = (int) reg[rs] * (int) reg[rt];
			hi = p >> 32L;
			lo = p & 0x00000000ffffffffL;
			break;
		case MULTU:
			p = (uint64_t) reg[rs] * (uint64_t) reg[rt];
			hi = p >> 32L;
			lo = p & 0x00000000ffffffffL;
			break;
		case DIV:
			lo = (int) reg[rs] / (int) reg[rt];
			hi = (int) reg[rs] % (int) reg[rt];
			break;
		case DIVU:
			lo = reg[rs] / reg[rt];
			hi = reg[rs] % reg[rt];
			break;
		case SLT:
			reg[rd] = ((int) reg[rs] < (int) reg[rt]) ? 1 : 0;
			break;
		case SLTU:
			reg[rd] = (reg[rs] < reg[rt]) ? 1 : 0;
			break;
		case MFHI:
			reg[rd] = hi;
			break;
		case MFLO:
			reg[rd] = lo;
			break;
		case MTHI:
			hi = reg[rs];
			break;
		case MTLO:
			lo = reg[rs];
			break;
		case JR:
			pc = reg[rs];
			break;
		case J:
			pc = (target << 2) | (pc & 0xf0000000);
			break;
		case JAL:
			reg[31] = pc;   // pc has been pre-incremented
			pc = (target << 2) | (pc & 0xf0000000);
			break;
		case JALR:
			reg[31] = pc;
			pc = reg[rs];
			break;
		case BEQ:
			// note pc was pre-incremented
			pc = (reg[rs] == reg[rt]) ? pc + (signExtend16(imm) << 2) - 4 : pc;
			break;
		case BNE:
			pc = (reg[rs] != reg[rt]) ? pc + (signExtend16(imm) << 2) - 4 : pc;
			break;
		case BGEZ:
			pc = ((int) reg[rs] >= 0) ? pc + (signExtend16(imm) << 2) - 4 : pc;
			break;
		case BGTZ:
			pc = ((int) reg[rs] > 0) ? pc + (signExtend16(imm) << 2) - 4 : pc;
			break;
		case BLEZ:
			pc = ((int) reg[rs] <= 0) ? pc + (signExtend16(imm) << 2) - 4 : pc;
			break;
		case BLTZ:
			pc = ((int) reg[rs] < 0) ? pc + (signExtend16(imm) << 2) - 4 : pc;
			break;
		case ADDI:
			reg[rt] = reg[rs] + signExtend16(imm);
			break;
		case ADDIU:
			reg[rt] = reg[rs] + signExtend16(imm);;
			break;
		case SLTI:
			reg[rt] = ((int) reg[rs] < (int) signExtend16(imm)) ? 1 : 0;
			break;
		case SLTIU:
			reg[rt] = (reg[rs] < signExtend16(imm)) ? 1 : 0;
			break;
		case ANDI:
			reg[rt] = reg[rs] & imm;
			break;
		case ORI:
			reg[rt] = reg[rs] | imm;
			break;
		case XORI:
			reg[rt] = reg[rs] ^ imm;
			break;
		case LUI:
			reg[rt] = (imm << 16);
			break;
		case LB:
			reg[rt] = signExtend8(M.read8(reg[rs] + signExtend16(imm)));
			break;
		case LH:
			reg[rt] = signExtend16(M.read16(reg[rs] + signExtend16(imm)));
			break;
		case LW:
			reg[rt] = M.read32(reg[rs] + signExtend16(imm));
			break;
		case LBU:
			reg[rt] = M.read8(reg[rs] + signExtend16(imm));
			break;
		case LHU:
			reg[rt] = M.read16(reg[rs] + signExtend16(imm));
			break;
		case SB:
			M.write8(reg[rt], reg[rs] + signExtend16(imm));
			break;
		case SH:
			M.write16(reg[rt], reg[rs] + signExtend16(imm));
			break;
		case SW:
			M.write32(reg[rt], reg[rs] + signExtend16(imm));
			break;
		case SYSCALL:
			switch (reg[2]) {
				case 1:
					printf("%d", reg[4]);
					break;
				case 4:
					printf("%s", M.getMemoryPtr(reg[4]));
					break;
				case 9:
					reg[2] = M.alloc(reg[4]);
					break;
				case 10:
					keepGoing = false;
					break;
				case 11:
					printf("%c", reg[4]);
					break;
				default:
					printf("Undefined syscall code: %d\n", reg[2]);
					//      assert(false && "undefined syscall code");
					break;
			}
			break;
		default:
			printf("undefined opcode: %u\n", opcode);
			assert(false);
			break;
	}
	++instructionCount;
	++itokenCounts[token];
	++xtypeCounts[xtype];
	return keepGoing;
}