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

Unified Diff: src/arm/macro-assembler-arm.cc

Issue 2497483002: [Turbofan] CodeGenerator for ARM avoids moves from VFP to general regs. (Closed)
Patch Set: Fix bug in VswpExtended. Created 4 years, 1 month 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/arm/macro-assembler-arm.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/macro-assembler-arm.cc
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index de8e14ef53422d6f45a14119ec1f0b87b768fb48..7f05fd6903c0cd7067b862cfad9588cb9f2e9d93 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -1051,66 +1051,151 @@ void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) {
}
}
-void MacroAssembler::VmovExtended(Register dst, int src_code) {
- DCHECK_LE(32, src_code);
- DCHECK_GT(64, src_code);
- if (src_code & 0x1) {
- VmovHigh(dst, DwVfpRegister::from_code(src_code / 2));
- } else {
- VmovLow(dst, DwVfpRegister::from_code(src_code / 2));
- }
-}
-
-void MacroAssembler::VmovExtended(int dst_code, Register src) {
- DCHECK_LE(32, dst_code);
- DCHECK_GT(64, dst_code);
- if (dst_code & 0x1) {
- VmovHigh(DwVfpRegister::from_code(dst_code / 2), src);
- } else {
- VmovLow(DwVfpRegister::from_code(dst_code / 2), src);
- }
-}
-
-void MacroAssembler::VmovExtended(int dst_code, int src_code,
- Register scratch) {
+void MacroAssembler::VmovExtended(int dst_code, int src_code) {
if (src_code < 32 && dst_code < 32) {
// src and dst are both s-registers.
vmov(SwVfpRegister::from_code(dst_code),
SwVfpRegister::from_code(src_code));
} else if (src_code < 32) {
- // src is an s-register.
- vmov(scratch, SwVfpRegister::from_code(src_code));
- VmovExtended(dst_code, scratch);
+ // src is s-register, dst is in high d-register. Move dst into scratch
+ // d-register to do the s-register move, then back.
+ DCHECK_GT(64, dst_code);
+ DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2);
+ int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1);
+ vmov(kScratchDoubleReg, dst_reg);
+ vmov(SwVfpRegister::from_code(dst_s_code),
+ SwVfpRegister::from_code(src_code));
+ vmov(dst_reg, kScratchDoubleReg);
} else if (dst_code < 32) {
- // dst is an s-register.
- VmovExtended(scratch, src_code);
- vmov(SwVfpRegister::from_code(dst_code), scratch);
+ // src is in high d-register, dst is an s-register. Move src into scratch
+ // d-register, do the s-register move.
+ DCHECK_GT(64, src_code);
+ DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2);
+ int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1);
+ vmov(kScratchDoubleReg, src_reg);
+ vmov(SwVfpRegister::from_code(dst_code),
+ SwVfpRegister::from_code(src_s_code));
} else {
- // Neither src or dst are s-registers.
+ // src and dst are in high d-registers. Move both into free registers,
+ // do the s-register move, then move dst back.
DCHECK_GT(64, src_code);
DCHECK_GT(64, dst_code);
- VmovExtended(scratch, src_code);
- VmovExtended(dst_code, scratch);
+ DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2);
+ DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2);
+ int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1);
+ int src_s_code = kDoubleRegZero.low().code() + (src_code & 1);
+ vmov(kScratchDoubleReg, dst_reg);
+ vmov(kDoubleRegZero, src_reg);
+ vmov(SwVfpRegister::from_code(dst_s_code),
+ SwVfpRegister::from_code(src_s_code));
+ vmov(dst_reg, kScratchDoubleReg);
+ vmov(kDoubleRegZero, 0.0); // restore zero register
}
}
-void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src,
- Register scratch) {
- if (dst_code >= 32) {
- ldr(scratch, src);
- VmovExtended(dst_code, scratch);
- } else {
+void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src) {
+ if (dst_code < 32) {
vldr(SwVfpRegister::from_code(dst_code), src);
+ } else {
+ // dst is in high d-register, move it down, load src, then move it back up.
+ DCHECK_GT(64, dst_code);
+ DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2);
+ int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1);
+ vmov(kScratchDoubleReg, dst_reg);
+ vldr(SwVfpRegister::from_code(dst_s_code), src);
+ vmov(dst_reg, kScratchDoubleReg);
+ }
+}
+void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code) {
+ if (src_code < 32) {
+ vstr(SwVfpRegister::from_code(src_code), dst);
+ } else {
+ // src is in high d-register, move it down, store src.
+ DCHECK_GT(64, src_code);
+ DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2);
+ int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1);
+ vmov(kScratchDoubleReg, src_reg);
+ vstr(SwVfpRegister::from_code(src_s_code), dst);
}
}
-void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code,
- Register scratch) {
- if (src_code >= 32) {
- VmovExtended(scratch, src_code);
- str(scratch, dst);
+void MacroAssembler::VswpExtended(int dst_code, int src_code) {
+ if (src_code < 32 && dst_code < 32) {
+ // src and dst are both s-registers.
+ vmov(kScratchDoubleReg.low(), SwVfpRegister::from_code(dst_code));
+ vmov(SwVfpRegister::from_code(dst_code),
+ SwVfpRegister::from_code(src_code));
+ vmov(SwVfpRegister::from_code(src_code), kScratchDoubleReg.low());
+ } else if (src_code < 32) {
+ // src is s-register, dst is in high d-register. Move dst into scratch
+ // d-register to do the s-register swap, then back.
+ DCHECK_GT(64, dst_code);
+ DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2);
+ int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1);
+ int dst_s_temp = kDoubleRegZero.low().code() + (dst_code & 1);
+ vmov(kScratchDoubleReg, dst_reg);
+ vmov(kDoubleRegZero, dst_reg);
+ vmov(SwVfpRegister::from_code(dst_s_code),
+ SwVfpRegister::from_code(src_code));
+ vmov(dst_reg, kScratchDoubleReg);
+ vmov(SwVfpRegister::from_code(src_code),
+ SwVfpRegister::from_code(dst_s_temp));
+ vmov(kDoubleRegZero, 0.0); // restore zero register
+ } else if (dst_code < 32) {
+ // src is in high d-register, dst is an s-register. Move src into scratch
+ // d-register, do the s-register swap.
+ DCHECK_GT(64, src_code);
+ DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2);
+ int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1);
+ int src_s_temp = kDoubleRegZero.low().code() + (src_code & 1);
+ vmov(kScratchDoubleReg, src_reg);
+ vmov(kDoubleRegZero, src_reg);
+ vmov(SwVfpRegister::from_code(src_s_code),
+ SwVfpRegister::from_code(dst_code));
+ vmov(src_reg, kScratchDoubleReg);
+ vmov(SwVfpRegister::from_code(dst_code),
+ SwVfpRegister::from_code(src_s_temp));
+ vmov(kDoubleRegZero, 0.0); // restore zero register
} else {
+ // src and dst are in high d-registers. Move both into free registers,
+ // do the s-register swap, then move both back.
+ DCHECK_GT(64, src_code);
+ DCHECK_GT(64, dst_code);
+ DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2);
+ DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2);
+ int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1);
+ int src_s_code = kDoubleRegZero.low().code() + (src_code & 1);
+ vmov(kScratchDoubleReg, dst_reg);
+ vmov(kDoubleRegZero, src_reg);
+ vmov(SwVfpRegister::from_code(src_s_code ^ 1),
+ SwVfpRegister::from_code(dst_s_code));
+ vmov(SwVfpRegister::from_code(dst_s_code),
+ SwVfpRegister::from_code(src_s_code));
+ vmov(dst_reg, kScratchDoubleReg);
+ vmov(kScratchDoubleReg, src_reg);
+ vmov(SwVfpRegister::from_code(dst_s_code),
+ SwVfpRegister::from_code(src_s_code ^ 1));
+ vmov(src_reg, kScratchDoubleReg);
+ vmov(kDoubleRegZero, 0.0); // restore zero register
+ }
+}
+
+void MacroAssembler::VswpExtended(const MemOperand& dst, int src_code) {
+ if (src_code < 32) {
+ vldr(kScratchDoubleReg.low(), dst);
vstr(SwVfpRegister::from_code(src_code), dst);
+ vmov(SwVfpRegister::from_code(src_code), kScratchDoubleReg.low());
+ } else {
+ // src is in high d-register, move it down, do the swap, move src back up.
+ DCHECK_GT(64, src_code);
+ DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2);
+ int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1);
+ vmov(kScratchDoubleReg, src_reg);
+ vldr(kDoubleRegZero.low(), dst);
+ vstr(SwVfpRegister::from_code(src_s_code), dst);
+ vmov(SwVfpRegister::from_code(src_s_code), kDoubleRegZero.low());
+ vmov(src_reg, kScratchDoubleReg);
+ vmov(kDoubleRegZero, 0.0); // restore zero register
}
}
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698