Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1179)

Unified Diff: src/mips64/simulator-mips64.cc

Issue 1195793002: MIPS: Implemented PC-relative instructions for R6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mips64/disasm-mips64.cc ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips64/simulator-mips64.cc
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
index fee93a867abbd4a721719d2eb5268fb2d5a761ae..2382f44fb8d731bcebb99e98f257abf8236b3113 100644
--- a/src/mips64/simulator-mips64.cc
+++ b/src/mips64/simulator-mips64.cc
@@ -2201,6 +2201,8 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t* alu_out,
const uint64_t rt_u = static_cast<uint64_t>(rt);
const int32_t rd_reg = instr->RdValue();
const uint64_t sa = instr->SaValue();
+ const uint8_t bp2 = instr->Bp2Value();
+ const uint8_t bp3 = instr->Bp3Value();
const int32_t fs_reg = instr->FsValue();
@@ -2335,7 +2337,8 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t* alu_out,
// MIPS spec: If no bits were set in GPR rs, the result written to
// GPR rd is 32.
DCHECK(instr->SaValue() == 1);
- *alu_out = base::bits::CountLeadingZeros32(rs_u);
+ *alu_out =
+ base::bits::CountLeadingZeros32(static_cast<int32_t>(rs_u));
}
break;
case MFLO:
@@ -2519,39 +2522,16 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t* alu_out,
*alu_out = static_cast<int64_t>((rs_u & (mask << lsb)) >> lsb);
break;
}
- case BITSWAP: { // Mips32r6 instruction
- uint32_t input = static_cast<uint32_t>(rt);
- uint32_t output = 0;
- uint8_t i_byte, o_byte;
-
- // Reverse the bit in byte for each individual byte
- for (int i = 0; i < 4; i++) {
- output = output >> 8;
- i_byte = input & 0xff;
-
- // Fast way to reverse bits in byte
- // Devised by Sean Anderson, July 13, 2001
- o_byte = static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
- (i_byte * 0x8020LU & 0x88440LU)) *
- 0x10101LU >>
- 16);
-
- output = output | (static_cast<uint32_t>(o_byte << 24));
- input = input >> 8;
- }
-
- *alu_out = static_cast<int64_t>(static_cast<int32_t>(output));
- break;
- }
- case DBITSWAP: {
- switch (instr->SaFieldRaw()) {
- case DBITSWAP_SA: { // Mips64r6
- uint64_t input = static_cast<uint64_t>(rt);
- uint64_t output = 0;
+ case BSHFL: {
+ int sa = instr->SaFieldRaw() >> kSaShift;
+ switch (sa) {
+ case BITSWAP: {
+ uint32_t input = static_cast<uint32_t>(rt);
+ uint32_t output = 0;
uint8_t i_byte, o_byte;
// Reverse the bit in byte for each individual byte
- for (int i = 0; i < 8; i++) {
+ for (int i = 0; i < 4; i++) {
output = output >> 8;
i_byte = input & 0xff;
@@ -2563,15 +2543,96 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t* alu_out,
0x10101LU >>
16);
- output = output | ((static_cast<uint64_t>(o_byte) << 56));
+ output = output | (static_cast<uint32_t>(o_byte << 24));
input = input >> 8;
}
- *alu_out = static_cast<int64_t>(output);
+ *alu_out = static_cast<int64_t>(static_cast<int32_t>(output));
break;
}
- default:
+ case SEB:
+ case SEH:
+ case WSBH:
UNREACHABLE();
+ break;
+ default: {
+ sa >>= kBp2Bits;
+ switch (sa) {
+ case ALIGN: {
+ if (bp2 == 0) {
+ *alu_out = static_cast<int32_t>(rt);
+ } else {
+ uint64_t rt_hi = rt << (8 * bp2);
+ uint64_t rs_lo = rs >> (8 * (4 - bp2));
+ *alu_out = static_cast<int32_t>(rt_hi | rs_lo);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case DBSHFL: {
+ int sa = instr->SaFieldRaw() >> kSaShift;
+ switch (sa) {
+ case DBITSWAP: {
+ switch (instr->SaFieldRaw() >> kSaShift) {
+ case DBITSWAP_SA: { // Mips64r6
+ uint64_t input = static_cast<uint64_t>(rt);
+ uint64_t output = 0;
+ uint8_t i_byte, o_byte;
+
+ // Reverse the bit in byte for each individual byte
+ for (int i = 0; i < 8; i++) {
+ output = output >> 8;
+ i_byte = input & 0xff;
+
+ // Fast way to reverse bits in byte
+ // Devised by Sean Anderson, July 13, 2001
+ o_byte =
+ static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
+ (i_byte * 0x8020LU & 0x88440LU)) *
+ 0x10101LU >>
+ 16);
+
+ output = output | ((static_cast<uint64_t>(o_byte) << 56));
+ input = input >> 8;
+ }
+
+ *alu_out = static_cast<int64_t>(output);
+ break;
+ }
+ }
+ break;
+ }
+ case DSBH:
+ case DSHD:
+ UNREACHABLE();
+ break;
+ default: {
+ sa >>= kBp3Bits;
+ switch (sa) {
+ case DALIGN: {
+ if (bp3 == 0) {
+ *alu_out = static_cast<int64_t>(rt);
+ } else {
+ uint64_t rt_hi = rt << (8 * bp3);
+ uint64_t rs_lo = rs >> (8 * (8 - bp3));
+ *alu_out = static_cast<int64_t>(rt_hi | rs_lo);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ }
}
break;
}
@@ -3853,8 +3914,8 @@ void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr,
set_register(rt_reg, alu_out);
TraceRegWr(alu_out);
break;
- case BITSWAP:
- case DBITSWAP:
+ case BSHFL:
+ case DBSHFL:
set_register(rd_reg, alu_out);
TraceRegWr(alu_out);
break;
@@ -3933,7 +3994,31 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
DecodeTypeRegisterSPECIAL2(instr, rd_reg, alu_out);
break;
case SPECIAL3:
- DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out);
+ switch (instr->FunctionFieldRaw()) {
+ case BSHFL: {
+ int sa = instr->SaValue();
+ sa >>= kBp2Bits;
+ switch (sa) {
+ case ALIGN: {
+ DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out);
+ break;
+ }
+ }
+ }
+ case DBSHFL: {
+ int sa = instr->SaValue();
+ sa >>= kBp3Bits;
+ switch (sa) {
+ case DALIGN: {
+ DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out);
+ break;
+ }
+ }
+ }
+ default:
+ DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out);
+ break;
+ }
break;
// Unimplemented opcodes raised an error in the configuration step before,
// so we can use the default here to set the destination register in common
@@ -3949,11 +4034,16 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
void Simulator::DecodeTypeImmediate(Instruction* instr) {
// Instruction fields.
Opcode op = instr->OpcodeFieldRaw();
+ int32_t rs_reg = instr->RsValue();
int64_t rs = get_register(instr->RsValue());
uint64_t rs_u = static_cast<uint64_t>(rs);
int32_t rt_reg = instr->RtValue(); // Destination register.
int64_t rt = get_register(rt_reg);
int16_t imm16 = instr->Imm16Value();
+ int32_t imm18 = instr->Imm18Value();
+ int32_t imm19 = instr->Imm19Value();
+ int32_t imm21 = instr->Imm21Value();
+ int32_t imm26 = instr->Imm26Value();
int32_t ft_reg = instr->FtValue(); // Destination register.
int64_t ft = get_fpu_register(ft_reg);
@@ -3962,11 +4052,17 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
uint64_t oe_imm16 = 0xffff & imm16;
// Sign extended immediate.
int64_t se_imm16 = imm16;
+ int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0);
+ int64_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfffffffffff80000 : 0);
+ int64_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfffffffffc000000 : 0);
+
// Get current pc.
int64_t current_pc = get_pc();
// Next pc.
int64_t next_pc = bad_ra;
+ // pc increment
+ int16_t pc_increment;
// Used for conditional branch instructions.
bool do_branch = false;
@@ -4080,6 +4176,33 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
case BGTZ:
do_branch = rs > 0;
break;
+ case POP66: {
+ if (rs_reg) { // BEQZC
+ int32_t se_imm21 =
+ static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits));
+ se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits);
+ if (rs == 0)
+ next_pc = current_pc + 4 + (se_imm21 << 2);
+ else
+ next_pc = current_pc + 4;
+ } else { // JIC
+ next_pc = rt + imm16;
+ }
+ break;
+ }
+ case BC: {
+ next_pc = current_pc + 4 + (se_imm26 << 2);
+ set_pc(next_pc);
+ pc_modified_ = true;
+ break;
+ }
+ case BALC: {
+ set_register(31, current_pc + 4);
+ next_pc = current_pc + 4 + (se_imm26 << 2);
+ set_pc(next_pc);
+ pc_modified_ = true;
+ break;
+ }
// ------------- Arithmetic instructions.
case ADDI:
case DADDI:
@@ -4213,10 +4336,83 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
case SDC1:
addr = rs + se_imm16;
break;
+ // ------------- JIALC and BNEZC instructions.
+ case POP76:
+ // Next pc.
+ next_pc = rt + se_imm16;
+ // The instruction after the jump is NOT executed.
+ pc_increment = Instruction::kInstrSize;
+ if (instr->IsLinkingInstruction()) {
+ set_register(31, current_pc + pc_increment);
+ }
+ set_pc(next_pc);
+ pc_modified_ = true;
+ break;
+ // ------------- PC-Relative instructions.
+ case PCREL: {
+ // rt field: checking 5-bits.
+ uint8_t rt = (imm21 >> kImm16Bits);
+ switch (rt) {
+ case ALUIPC:
+ addr = current_pc + (se_imm16 << 16);
+ alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
+ break;
+ case AUIPC:
+ alu_out = current_pc + (se_imm16 << 16);
+ break;
+ default: {
+ // rt field: checking the most significant 3-bits.
+ rt = (imm21 >> kImm18Bits);
+ switch (rt) {
+ case LDPC:
+ addr =
+ (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3);
+ alu_out = Read2W(addr, instr);
+ break;
+ default: {
+ // rt field: checking the most significant 2-bits.
+ rt = (imm21 >> kImm19Bits);
+ switch (rt) {
+ case LWUPC: {
+ int32_t offset = imm19;
+ // Set sign.
+ offset <<= (kOpcodeBits + kRsBits + 2);
+ offset >>= (kOpcodeBits + kRsBits + 2);
+ addr = current_pc + (offset << 2);
+ uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
+ alu_out = *ptr;
+ break;
+ }
+ case LWPC: {
+ int32_t offset = imm19;
+ // Set sign.
+ offset <<= (kOpcodeBits + kRsBits + 2);
+ offset >>= (kOpcodeBits + kRsBits + 2);
+ addr = current_pc + (offset << 2);
+ int32_t* ptr = reinterpret_cast<int32_t*>(addr);
+ alu_out = *ptr;
+ break;
+ }
+ case ADDIUPC:
+ alu_out = current_pc + (se_imm19 << 2);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
default:
UNREACHABLE();
}
+
// ---------- Raise exceptions triggered.
SignalExceptions();
@@ -4298,6 +4494,8 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
addr = rs + se_imm16;
WriteD(addr, get_fpu_register_double(ft_reg), instr);
break;
+ case PCREL:
+ set_register(rs_reg, alu_out);
default:
break;
}
« no previous file with comments | « src/mips64/disasm-mips64.cc ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698