8319973: AArch64: Save and restore FPCR in the call stub
Reviewed-by: adinn, stuefe
This commit is contained in:
parent
04fd17e6a9
commit
6e86904a94
src/hotspot/cpu/aarch64
@ -1088,8 +1088,8 @@ public:
|
||||
#undef INSN
|
||||
|
||||
// we only provide mrs and msr for the special purpose system
|
||||
// registers where op1 (instr[20:19]) == 11 and, (currently) only
|
||||
// use it for FPSR n.b msr has L (instr[21]) == 0 mrs has L == 1
|
||||
// registers where op1 (instr[20:19]) == 11
|
||||
// n.b msr has L (instr[21]) == 0 mrs has L == 1
|
||||
|
||||
void msr(int op1, int CRn, int CRm, int op2, Register rt) {
|
||||
starti;
|
||||
|
@ -93,7 +93,7 @@
|
||||
// Entry frames
|
||||
// n.b. these values are determined by the layout defined in
|
||||
// stubGenerator for the Java call stub
|
||||
entry_frame_after_call_words = 27,
|
||||
entry_frame_after_call_words = 29,
|
||||
entry_frame_call_wrapper_offset = -8,
|
||||
|
||||
// we don't need a save area
|
||||
|
@ -571,6 +571,19 @@ public:
|
||||
msr(0b011, 0b0100, 0b0100, 0b001, zr);
|
||||
}
|
||||
|
||||
// FPCR : op1 == 011
|
||||
// CRn == 0100
|
||||
// CRm == 0100
|
||||
// op2 == 000
|
||||
|
||||
inline void get_fpcr(Register reg) {
|
||||
mrs(0b11, 0b0100, 0b0100, 0b000, reg);
|
||||
}
|
||||
|
||||
inline void set_fpcr(Register reg) {
|
||||
msr(0b011, 0b0100, 0b0100, 0b000, reg);
|
||||
}
|
||||
|
||||
// DCZID_EL0: op1 == 011
|
||||
// CRn == 0000
|
||||
// CRm == 0000
|
||||
|
@ -141,7 +141,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// [ return_from_Java ] <--- sp
|
||||
// [ argument word n ]
|
||||
// ...
|
||||
// -27 [ argument word 1 ]
|
||||
// -29 [ argument word 1 ]
|
||||
// -28 [ saved Floating-point Control Register ]
|
||||
// -26 [ saved v15 ] <--- sp_after_call
|
||||
// -25 [ saved v14 ]
|
||||
// -24 [ saved v13 ]
|
||||
@ -173,8 +174,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// Call stub stack layout word offsets from fp
|
||||
enum call_stub_layout {
|
||||
sp_after_call_off = -26,
|
||||
sp_after_call_off = -28,
|
||||
|
||||
fpcr_off = sp_after_call_off,
|
||||
d15_off = -26,
|
||||
d13_off = -24,
|
||||
d11_off = -22,
|
||||
@ -204,8 +206,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubCodeMark mark(this, "StubRoutines", "call_stub");
|
||||
address start = __ pc();
|
||||
|
||||
const Address sp_after_call(rfp, sp_after_call_off * wordSize);
|
||||
const Address sp_after_call (rfp, sp_after_call_off * wordSize);
|
||||
|
||||
const Address fpcr_save (rfp, fpcr_off * wordSize);
|
||||
const Address call_wrapper (rfp, call_wrapper_off * wordSize);
|
||||
const Address result (rfp, result_off * wordSize);
|
||||
const Address result_type (rfp, result_type_off * wordSize);
|
||||
@ -254,6 +257,14 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ stpd(v13, v12, d13_save);
|
||||
__ stpd(v15, v14, d15_save);
|
||||
|
||||
__ get_fpcr(rscratch1);
|
||||
__ str(rscratch1, fpcr_save);
|
||||
// Set FPCR to the state we need. We do want Round to Nearest. We
|
||||
// don't want non-IEEE rounding modes or floating-point traps.
|
||||
__ bfi(rscratch1, zr, 22, 4); // Clear DN, FZ, and Rmode
|
||||
__ bfi(rscratch1, zr, 8, 5); // Clear exception-control bits (8-12)
|
||||
__ set_fpcr(rscratch1);
|
||||
|
||||
// install Java thread in global register now we have saved
|
||||
// whatever value it held
|
||||
__ mov(rthread, c_rarg7);
|
||||
@ -367,6 +378,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ ldp(r22, r21, r22_save);
|
||||
__ ldp(r20, r19, r20_save);
|
||||
|
||||
// restore fpcr
|
||||
__ ldr(rscratch1, fpcr_save);
|
||||
__ set_fpcr(rscratch1);
|
||||
|
||||
__ ldp(c_rarg0, c_rarg1, call_wrapper);
|
||||
__ ldrw(c_rarg2, result_type);
|
||||
__ ldr(c_rarg3, method);
|
||||
|
Loading…
x
Reference in New Issue
Block a user