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

Unified Diff: runtime/vm/assembler_mips.h

Issue 14206002: Adds some floating point instructions to MIPS simulator, assembler, disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 | « no previous file | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_mips.h
===================================================================
--- runtime/vm/assembler_mips.h (revision 21293)
+++ runtime/vm/assembler_mips.h (working copy)
@@ -223,12 +223,23 @@
}
// CPU instructions in alphabetical order.
+ void addd(FRegister fd, FRegister fs, FRegister ft) {
+ ASSERT(EvenFPURegister(fd));
+ ASSERT(EvenFPURegister(fs));
+ ASSERT(EvenFPURegister(ft));
+ EmitFpuRType(COP1, FMT_D, ft, fs, fd, COP1_ADD);
+ }
+
void addiu(Register rt, Register rs, const Immediate& imm) {
ASSERT(Utils::IsInt(kImmBits, imm.value()));
const uint16_t imm_value = static_cast<uint16_t>(imm.value());
EmitIType(ADDIU, rs, rt, imm_value);
}
+ void adds(FRegister fd, FRegister fs, FRegister ft) {
+ EmitFpuRType(COP1, FMT_S, ft, fs, fd, COP1_ADD);
+ }
+
void addu(Register rd, Register rs, Register rt) {
EmitRType(SPECIAL, rs, rt, rd, 0, ADDU);
}
@@ -388,6 +399,11 @@
EmitLoadStore(LBU, rt, addr);
}
+ void ldc1(FRegister ft, const Address& addr) {
+ ASSERT(EvenFPURegister(ft));
+ EmitFpuLoadStore(LDC1, ft, addr);
+ }
+
void lh(Register rt, const Address& addr) {
EmitLoadStore(LH, rt, addr);
}
@@ -406,6 +422,17 @@
EmitLoadStore(LW, rt, addr);
}
+ void lwc1(FRegister ft, const Address& addr) {
+ EmitFpuLoadStore(LWC1, ft, addr);
+ }
+
+ void mfc1(Register rt, FRegister fs) {
+ Emit(COP1 << kOpcodeShift |
+ COP1_MF << kCop1SubShift |
+ rt << kRtShift |
+ fs << kFsShift);
+ }
+
void mfhi(Register rd) {
EmitRType(SPECIAL, R0, R0, rd, 0, MFHI);
}
@@ -418,6 +445,12 @@
or_(rd, rs, ZR);
}
+ void movd(FRegister fd, FRegister fs) {
+ ASSERT(EvenFPURegister(fd));
+ ASSERT(EvenFPURegister(fs));
+ EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_MOV);
+ }
+
void movn(Register rd, Register rs, Register rt) {
EmitRType(SPECIAL, rs, rt, rd, 0, MOVN);
}
@@ -426,6 +459,17 @@
EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ);
}
+ void movs(FRegister fd, FRegister fs) {
+ EmitFpuRType(COP1, FMT_S, F0, fs, fd, COP1_MOV);
+ }
+
+ void mtc1(Register rt, FRegister fs) {
+ Emit(COP1 << kOpcodeShift |
+ COP1_MT << kCop1SubShift |
+ rt << kRtShift |
+ fs << kFsShift);
+ }
+
void mult(Register rs, Register rt) {
EmitRType(SPECIAL, rs, rt, R0, 0, MULT);
}
@@ -456,6 +500,11 @@
EmitLoadStore(SB, rt, addr);
}
+ void sdc1(FRegister ft, const Address& addr) {
+ ASSERT(EvenFPURegister(ft));
+ EmitFpuLoadStore(SDC1, ft, addr);
+ }
+
void sh(Register rt, const Address& addr) {
EmitLoadStore(SH, rt, addr);
}
@@ -500,6 +549,10 @@
EmitLoadStore(SW, rt, addr);
}
+ void swc1(FRegister ft, const Address& addr) {
+ EmitFpuLoadStore(SWC1, ft, addr);
+ }
+
void xor_(Register rd, Register rs, Register rt) {
EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
}
@@ -565,6 +618,36 @@
}
}
+ void LoadImmediate(FRegister rd, double value) {
+ ASSERT(EvenFPURegister(rd));
+ const int64_t ival = bit_cast<uint64_t, double>(value);
+ const int32_t low = Utils::Low32Bits(ival);
+ const int32_t high = Utils::High32Bits(ival);
+ if (low != 0) {
+ LoadImmediate(TMP1, low);
+ mtc1(TMP1, rd);
+ } else {
+ mtc1(ZR, rd);
+ }
+
+ if (high != 0) {
+ LoadImmediate(TMP1, high);
+ mtc1(TMP1, static_cast<FRegister>(rd + 1));
+ } else {
+ mtc1(ZR, static_cast<FRegister>(rd + 1));
+ }
+ }
+
+ void LoadImmediate(FRegister rd, float value) {
regis 2013/04/12 17:08:56 I am not sure we will need this one, since there i
zra 2013/04/12 17:19:26 I'll keep it for now since I use it in some tests,
+ const int32_t ival = bit_cast<int32_t, float>(value);
+ if (ival == 0) {
+ mtc1(ZR, rd);
+ } else {
+ LoadImmediate(TMP1, ival);
+ mtc1(TMP1, rd);
+ }
+ }
+
void AddImmediate(Register rd, Register rs, int32_t value) {
if (Utils::IsInt(kImmBits, value)) {
addiu(rd, rs, Immediate(value));
@@ -734,6 +817,10 @@
GrowableArray<CodeComment*> comments_;
+ bool EvenFPURegister(FRegister reg) {
+ return (static_cast<int>(reg) & 1) == 0;
+ }
+
void Emit(int32_t value) {
// Emitting an instruction clears the delay slot state.
in_delay_slot_ = false;
@@ -761,6 +848,13 @@
addr.encoding());
}
+ void EmitFpuLoadStore(Opcode opcode, FRegister ft,
+ const Address &addr) {
+ Emit(opcode << kOpcodeShift |
+ ft << kFtShift |
+ addr.encoding());
+ }
+
void EmitRegImmType(Opcode opcode,
Register rs,
RtRegImm code,
@@ -790,6 +884,20 @@
func << kFunctionShift);
}
+ void EmitFpuRType(Opcode opcode,
+ Format fmt,
+ FRegister ft,
+ FRegister fs,
+ FRegister fd,
+ Cop1Function func) {
+ Emit(opcode << kOpcodeShift |
+ fmt << kFmtShift |
+ ft << kFtShift |
+ fs << kFsShift |
+ fd << kFdShift |
+ func << kCop1FnShift);
+ }
+
void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
if (label->IsBound()) {
// Relative destination from an instruction after the branch.
« no previous file with comments | « no previous file | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698