diff options
Diffstat (limited to 'powerpc/Asmexpand.ml')
-rw-r--r-- | powerpc/Asmexpand.ml | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml index cb6a659f..e663226f 100644 --- a/powerpc/Asmexpand.ml +++ b/powerpc/Asmexpand.ml @@ -177,34 +177,56 @@ let expand_builtin_memcpy sz al args = let expand_volatile_access (mk1: ireg -> constant -> unit) (mk2: ireg -> ireg -> unit) + ?(ofs_unaligned = true) addr temp = match addr with | BA(IR r) -> mk1 r (Cint _0) | BA_addrstack ofs -> - if offset_in_range ofs then - mk1 GPR1 (Cint ofs) + if ofs_unaligned || Int.eq (Int.mods ofs _4) _0 then + if offset_in_range ofs then + mk1 GPR1 (Cint ofs) + else begin + emit (Paddis(temp, GPR1, Cint (Asmgen.high_s ofs))); + mk1 temp (Cint (Asmgen.low_s ofs)) + end else begin - emit (Paddis(temp, GPR1, Cint (Asmgen.high_s ofs))); - mk1 temp (Cint (Asmgen.low_s ofs)) + emit (Paddis (temp, GPR1, Cint (Asmgen.high_s ofs))); + emit (Paddi (temp, temp, Cint (Asmgen.low_s ofs))); + mk1 temp (Cint _0) end | BA_addrglobal(id, ofs) -> if symbol_is_small_data id ofs then - mk1 GPR0 (Csymbol_sda(id, ofs)) + if ofs_unaligned || Asmgen.symbol_ofs_word_aligned id ofs then + mk1 GPR0 (Csymbol_sda(id, ofs)) + else begin + emit (Paddi (temp, GPR0, (Csymbol_sda (id,ofs)))); + mk1 temp (Cint _0) + end else if symbol_is_rel_data id ofs then begin emit (Paddis(temp, GPR0, Csymbol_rel_high(id, ofs))); emit (Paddi(temp, temp, Csymbol_rel_low(id, ofs))); mk1 temp (Cint _0) - end else begin + end else if ofs_unaligned || Asmgen.symbol_ofs_word_aligned id ofs then begin emit (Paddis(temp, GPR0, Csymbol_high(id, ofs))); mk1 temp (Csymbol_low(id, ofs)) + end else begin + emit (Paddis (temp, GPR0, (Csymbol_high (id, ofs)))); + emit (Paddi (temp, temp, (Csymbol_low (id, ofs)))); + mk1 temp (Cint _0) end | BA_addptr(BA(IR r), BA_int n) -> - if offset_in_range n then - mk1 r (Cint n) + if ofs_unaligned || Int.eq (Int.mods n _4) _0 then + if offset_in_range n then + mk1 r (Cint n) + else begin + emit (Paddis(temp, r, Cint (Asmgen.high_s n))); + mk1 temp (Cint (Asmgen.low_s n)) + end else begin - emit (Paddis(temp, r, Cint (Asmgen.high_s n))); - mk1 temp (Cint (Asmgen.low_s n)) + emit (Paddis (temp, r, Cint (Asmgen.high_s n))); + emit (Paddi (temp, temp, Cint (Asmgen.low_s n))); + mk1 temp (Cint _0) end | BA_addptr(BA_addrglobal(id, ofs), BA(IR r)) -> if symbol_is_small_data id ofs then begin @@ -215,9 +237,14 @@ let expand_volatile_access emit (Paddis(temp, GPR0, Csymbol_rel_high(id, ofs))); emit (Paddi(temp, temp, Csymbol_rel_low(id, ofs))); mk2 temp GPR0 - end else begin + end else if ofs_unaligned || Asmgen.symbol_ofs_word_aligned id ofs then begin emit (Paddis(temp, r, Csymbol_high(id, ofs))); mk1 temp (Csymbol_low(id, ofs)) + end else begin + emit (Pmr (GPR0, r)); + emit (Paddis(temp, GPR0, Csymbol_high(id, ofs))); + emit (Paddi(temp, temp, Csymbol_low(id, ofs))); + mk2 temp GPR0 end | BA_addptr(BA(IR r1), BA(IR r2)) -> mk2 r1 r2 @@ -283,6 +310,7 @@ let expand_builtin_vload_1 chunk addr res = expand_volatile_access (fun r c -> emit (Pld(res, c, r))) (fun r1 r2 -> emit (Pldx(res, r1, r2))) + ~ofs_unaligned:false addr GPR11 | Mint64, BR_splitlong(BR(IR hi), BR(IR lo)) -> expand_volatile_access @@ -346,6 +374,7 @@ let expand_builtin_vstore_1 chunk addr src = expand_volatile_access (fun r c -> emit (Pstd(src, c, r))) (fun r1 r2 -> emit (Pstdx(src, r1, r2))) + ~ofs_unaligned:false addr temp | Mint64, BA_splitlong(BA(IR hi), BA(IR lo)) -> expand_volatile_access @@ -388,8 +417,9 @@ let rec next_arg_locations ir fr ofs = function then next_arg_locations ir (fr + 1) ofs l else next_arg_locations ir fr (align ofs 8 + 8) l | Tlong :: l -> - if ir < 7 - then next_arg_locations (align ir 2 + 2) fr ofs l + let ir = align ir 2 in + if ir < 8 + then next_arg_locations (ir + 2) fr ofs l else next_arg_locations ir fr (align ofs 8 + 8) l let expand_builtin_va_start r = @@ -763,6 +793,9 @@ let expand_builtin_inline name args res = (* no operation *) | "__builtin_nop", [], _ -> emit (Pori (GPR0, GPR0, Cint _0)) + (* Optimization hint *) + | "__builtin_unreachable", [], _ -> + () (* atomic operations *) | "__builtin_atomic_exchange", [BA (IR a1); BA (IR a2); BA (IR a3)],_ -> (* Register constraints imposed by Machregs.v *) @@ -830,7 +863,7 @@ let expand_builtin_inline name args res = function is unprototyped. *) let set_cr6 sg = - if sg.sig_cc.cc_vararg || sg.sig_cc.cc_unproto then begin + if (sg.sig_cc.cc_vararg <> None) || sg.sig_cc.cc_unproto then begin if List.exists (function Tfloat | Tsingle -> true | _ -> false) sg.sig_args then emit (Pcreqv(CRbit_6, CRbit_6, CRbit_6)) else emit (Pcrxor(CRbit_6, CRbit_6, CRbit_6)) |