8319973: AArch64: Save and restore FPCR in the call stub

Reviewed-by: adinn, stuefe
This commit is contained in:
Andrew Haley 2023-11-20 16:38:05 +00:00
parent 04fd17e6a9
commit 6e86904a94
4 changed files with 34 additions and 6 deletions

@ -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);