Chromium Code Reviews| Index: src/mips/assembler-mips.cc |
| =================================================================== |
| --- src/mips/assembler-mips.cc (revision 4259) |
| +++ src/mips/assembler-mips.cc (working copy) |
| @@ -42,7 +42,35 @@ |
| namespace internal { |
| +// Safe default is no features. |
| +unsigned CpuFeatures::supported_ = 0; |
| +unsigned CpuFeatures::enabled_ = 0; |
| +unsigned CpuFeatures::found_by_runtime_probing_ = 0; |
| +void CpuFeatures::Probe() { |
| + // If the compiler is allowed to use fpu then we can use fpu too in our |
| + // code generation. |
| +#if !defined(__mips__) |
| + // For the simulator=mips build, use FPU when FLAG_enable_fpu is enabled. |
| + if (FLAG_enable_fpu) { |
| + supported_ |= 1u << FPU; |
|
Søren Thygesen Gjesse
2010/05/25 09:00:56
Only 2 space indent.
|
| + } |
| +#else |
| + if (Serializer::enabled()) { |
| + supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
| + return; // No features if we might serialize. |
| + } |
| + |
| + if (OS::MipsCpuHasFeature(FPU)) { |
| + // This implementation also sets the FPU flags if |
| + // runtime detection of FPU returns true. |
| + supported_ |= 1u << FPU; |
| + found_by_runtime_probing_ |= 1u << FPU; |
| + } |
| +#endif |
| +} |
| + |
| + |
| const Register no_reg = { -1 }; |
| const Register zero_reg = { 0 }; |
| @@ -467,14 +495,27 @@ |
| void Assembler::GenInstrRegister(Opcode opcode, |
| + Register rs, |
| + Register rt, |
| + uint16_t msb, |
| + uint16_t lsb, |
| + SecondaryField func) { |
| + ASSERT(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb)); |
| + Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) |
| + | (msb << kRdShift) | (lsb << kSaShift) | func; |
| + emit(instr); |
| +} |
| + |
| + |
| +void Assembler::GenInstrRegister(Opcode opcode, |
| SecondaryField fmt, |
| FPURegister ft, |
| FPURegister fs, |
| FPURegister fd, |
| SecondaryField func) { |
| ASSERT(fd.is_valid() && fs.is_valid() && ft.is_valid()); |
| - Instr instr = opcode | fmt | (ft.code() << 16) | (fs.code() << kFsShift) |
| - | (fd.code() << 6) | func; |
| + Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift) |
| + | (fd.code() << kFdShift) | func; |
| emit(instr); |
| } |
| @@ -487,7 +528,7 @@ |
| SecondaryField func) { |
| ASSERT(fd.is_valid() && fs.is_valid() && rt.is_valid()); |
| Instr instr = opcode | fmt | (rt.code() << kRtShift) |
| - | (fs.code() << kFsShift) | (fd.code() << 6) | func; |
| + | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func; |
| emit(instr); |
| } |
| @@ -647,31 +688,16 @@ |
| // Arithmetic. |
| -void Assembler::add(Register rd, Register rs, Register rt) { |
| - GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADD); |
| -} |
| - |
| - |
| void Assembler::addu(Register rd, Register rs, Register rt) { |
| GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); |
| } |
| -void Assembler::addi(Register rd, Register rs, int32_t j) { |
| - GenInstrImmediate(ADDI, rs, rd, j); |
| -} |
| - |
| - |
| void Assembler::addiu(Register rd, Register rs, int32_t j) { |
| GenInstrImmediate(ADDIU, rs, rd, j); |
| } |
| -void Assembler::sub(Register rd, Register rs, Register rt) { |
| - GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUB); |
| -} |
| - |
| - |
| void Assembler::subu(Register rd, Register rs, Register rt) { |
| GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU); |
| } |
| @@ -782,6 +808,16 @@ |
| } |
| +void Assembler::lh(Register rd, const MemOperand& rs) { |
| + GenInstrImmediate(LH, rs.rm(), rd, rs.offset_); |
| +} |
| + |
| + |
| +void Assembler::lhu(Register rd, const MemOperand& rs) { |
| + GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_); |
| +} |
| + |
| + |
| void Assembler::lw(Register rd, const MemOperand& rs) { |
| GenInstrImmediate(LW, rs.rm(), rd, rs.offset_); |
| } |
| @@ -792,6 +828,11 @@ |
| } |
| +void Assembler::sh(Register rd, const MemOperand& rs) { |
| + GenInstrImmediate(SH, rs.rm(), rd, rs.offset_); |
| +} |
| + |
| + |
| void Assembler::sw(Register rd, const MemOperand& rs) { |
| GenInstrImmediate(SW, rs.rm(), rd, rs.offset_); |
| } |
| @@ -892,7 +933,35 @@ |
| GenInstrImmediate(SLTIU, rs, rt, j); |
| } |
| +// Conditional move. |
| +void Assembler::movz(Register rd, Register rs, Register rt) { |
| + GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ); |
| +} |
| + |
| +void Assembler::movn(Register rd, Register rs, Register rt) { |
| + GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN); |
| +} |
| + |
| +// Bit twiddling. |
| +void Assembler::clz(Register rd, Register rs) { |
| + // Clz instr requires same GPR number in 'rd' and 'rt' fields. |
| + GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ); |
| +} |
| + |
| + |
| +void Assembler::ins(Register rt, Register rs, uint16_t pos, uint16_t size) { |
| + // Ins instr has 'rt' field as dest, and two uint5: msb, lsb |
| + GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS); |
| +} |
| + |
| + |
| +void Assembler::ext(Register rt, Register rs, uint16_t pos, uint16_t size) { |
| + // Ext instr has 'rt' field as dest, and two uint5: msb, lsb |
| + GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, EXT); |
| +} |
| + |
| + |
| //--------Coprocessor-instructions---------------- |
| // Load, store, move. |
| @@ -902,7 +971,14 @@ |
| void Assembler::ldc1(FPURegister fd, const MemOperand& src) { |
| - GenInstrImmediate(LDC1, src.rm(), fd, src.offset_); |
| + // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit |
| + // load to two 32-bit loads. This really should be done in macro-assembler, |
|
Søren Thygesen Gjesse
2010/05/25 09:00:56
I think you should just remove "This really should
|
| + // but this should be temporary.... |
| + GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); |
| + FPURegister nextfpreg; |
| + nextfpreg.setcode(fd.code() + 1); |
| + GenInstrImmediate(LWC1, src.rm(), nextfpreg, src.offset_ + 4); |
| + // GenInstrImmediate(LDC1, src.rm(), fd, src.offset_); |
|
Søren Thygesen Gjesse
2010/05/25 09:00:56
Please remove code in comments.
|
| } |
| @@ -912,30 +988,58 @@ |
| void Assembler::sdc1(FPURegister fd, const MemOperand& src) { |
| - GenInstrImmediate(SDC1, src.rm(), fd, src.offset_); |
| + // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit |
| + // store to two 32-bit stores. This really should be done in macro-assembler, |
|
Søren Thygesen Gjesse
2010/05/25 09:00:56
Ditto.
|
| + // but this should be temporary.... |
| + GenInstrImmediate(SWC1, src.rm(), fd, src.offset_); |
| + FPURegister nextfpreg; |
| + nextfpreg.setcode(fd.code() + 1); |
| + GenInstrImmediate(SWC1, src.rm(), nextfpreg, src.offset_ + 4); |
| + // GenInstrImmediate(SDC1, src.rm(), fd, src.offset_); |
|
Søren Thygesen Gjesse
2010/05/25 09:00:56
Ditto.
|
| } |
| -void Assembler::mtc1(FPURegister fs, Register rt) { |
| +void Assembler::mtc1(Register rt, FPURegister fs) { |
| GenInstrRegister(COP1, MTC1, rt, fs, f0); |
| } |
| -void Assembler::mthc1(FPURegister fs, Register rt) { |
| - GenInstrRegister(COP1, MTHC1, rt, fs, f0); |
| +void Assembler::mfc1(Register rt, FPURegister fs) { |
| + GenInstrRegister(COP1, MFC1, rt, fs, f0); |
| } |
| -void Assembler::mfc1(FPURegister fs, Register rt) { |
| - GenInstrRegister(COP1, MFC1, rt, fs, f0); |
| +// Arithmetic. |
| + |
| +void Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) { |
| + GenInstrRegister(COP1, D, ft, fs, fd, ADD_D); |
| } |
| +void Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) { |
| + GenInstrRegister(COP1, D, ft, fs, fd, SUB_D); |
| +} |
| -void Assembler::mfhc1(FPURegister fs, Register rt) { |
| - GenInstrRegister(COP1, MFHC1, rt, fs, f0); |
| +void Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) { |
| + GenInstrRegister(COP1, D, ft, fs, fd, MUL_D); |
| } |
| +void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) { |
| + GenInstrRegister(COP1, D, ft, fs, fd, DIV_D); |
| +} |
| +void Assembler::abs_d(FPURegister fd, FPURegister fs) { |
| + GenInstrRegister(COP1, D, f0, fs, fd, ABS_D); |
| +} |
| + |
| +void Assembler::mov_d(FPURegister fd, FPURegister fs) { |
| + GenInstrRegister(COP1, D, f0, fs, fd, MOV_D); |
| +} |
| + |
| +void Assembler::neg_d(FPURegister fd, FPURegister fs) { |
| + GenInstrRegister(COP1, D, f0, fs, fd, NEG_D); |
| +} |
| + |
| + |
| // Conversions. |
| void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) { |
| @@ -990,7 +1094,7 @@ |
| // Conditions. |
| void Assembler::c(FPUCondition cond, SecondaryField fmt, |
| - FPURegister ft, FPURegister fs, uint16_t cc) { |
| + FPURegister fs, FPURegister ft, uint16_t cc) { |
| ASSERT(is_uint3(cc)); |
| ASSERT((fmt & ~(31 << kRsShift)) == 0); |
| Instr instr = COP1 | fmt | ft.code() << 16 | fs.code() << kFsShift |