aboutsummaryrefslogtreecommitdiffstats
path: root/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'powerpc')
-rw-r--r--powerpc/Asm.v10
-rw-r--r--powerpc/AsmToJSON.ml6
-rw-r--r--powerpc/Asmexpand.ml100
-rw-r--r--powerpc/Asmgen.v2
-rw-r--r--powerpc/CBuiltins.ml12
-rw-r--r--powerpc/Machregs.v6
-rw-r--r--powerpc/TargetPrinter.ml6
7 files changed, 72 insertions, 70 deletions
diff --git a/powerpc/Asm.v b/powerpc/Asm.v
index 863ed6a1..3c7bdd15 100644
--- a/powerpc/Asm.v
+++ b/powerpc/Asm.v
@@ -142,7 +142,7 @@ Inductive instruction : Type :=
| Paddic: ireg -> ireg -> constant -> instruction (**r add immediate and set carry *)
| Paddis: ireg -> ireg -> constant -> instruction (**r add immediate high *)
| Paddze: ireg -> ireg -> instruction (**r add carry *)
- | Pallocframe: Z -> int -> instruction (**r allocate new stack frame (pseudo) *)
+ | Pallocframe: Z -> int -> int -> instruction (**r allocate new stack frame (pseudo) *)
| Pand_: ireg -> ireg -> ireg -> instruction (**r bitwise and *)
| Pandc: ireg -> ireg -> ireg -> instruction (**r bitwise and-complement *)
| Pandi_: ireg -> ireg -> constant -> instruction (**r and immediate and set conditions *)
@@ -157,6 +157,7 @@ Inductive instruction : Type :=
| Pblr: instruction (**r branch to contents of register LR *)
| Pbt: crbit -> label -> instruction (**r branch if true *)
| Pbtbl: ireg -> list label -> instruction (**r N-way branch through a jump table (pseudo) *)
+ | Pcmpb: ireg -> ireg -> ireg -> instruction (**r compare bytes *)
| Pcmplw: ireg -> ireg -> instruction (**r unsigned integer comparison *)
| Pcmplwi: ireg -> constant -> instruction (**r same, with immediate argument *)
| Pcmpw: ireg -> ireg -> instruction (**r signed integer comparison *)
@@ -206,6 +207,7 @@ Inductive instruction : Type :=
| Pfrsqrte: freg -> freg -> instruction (**r approximate reciprocal of square root *)
| Pfres: freg -> freg -> instruction (**r approximate inverse *)
| Pfsel: freg -> freg -> freg -> freg -> instruction (**r FP conditional move *)
+ | Pisel: ireg -> ireg -> ireg -> crbit -> instruction (**r integer select *)
| Pisync: instruction (**r ISYNC barrier *)
| Picbi: ireg -> ireg -> instruction (**r instruction cache invalidate *)
| Picbtls: int -> ireg -> ireg -> instruction (**r instruction cache block touch and lock set *)
@@ -323,7 +325,7 @@ lbl: .double floatcst
lfd rdst, 0(r1)
addi r1, r1, 8
>>
-- [Pallocframe sz ofs]: in the formal semantics, this pseudo-instruction
+- [Pallocframe sz ofs retofs]: in the formal semantics, this pseudo-instruction
allocates a memory block with bounds [0] and [sz], stores the value
of register [r1] (the stack pointer, by convention) at offset [ofs]
in this block, and sets [r1] to a pointer to the bottom of this
@@ -622,7 +624,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Paddze rd r1 =>
Next (nextinstr (rs#rd <- (Val.add rs#r1 rs#CARRY)
#CARRY <- (Val.add_carry rs#r1 Vzero rs#CARRY))) m
- | Pallocframe sz ofs =>
+ | Pallocframe sz ofs _ =>
let (m1, stk) := Mem.alloc m 0 sz in
let sp := Vptr stk Int.zero in
match Mem.storev Mint32 m1 (Val.add sp (Vint ofs)) rs#GPR1 with
@@ -871,6 +873,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
(** The following instructions and directives are not generated
directly by [Asmgen], so we do not model them. *)
| Pbdnz _
+ | Pcmpb _ _ _
| Pcntlzw _ _
| Pcreqv _ _ _
| Pcrxor _ _ _
@@ -891,6 +894,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Pfrsqrte _ _
| Pfres _ _
| Pfsel _ _ _ _
+ | Pisel _ _ _ _
| Plwarx _ _ _
| Plwbrx _ _ _
| Picbi _ _
diff --git a/powerpc/AsmToJSON.ml b/powerpc/AsmToJSON.ml
index 5f875ebf..a7e66701 100644
--- a/powerpc/AsmToJSON.ml
+++ b/powerpc/AsmToJSON.ml
@@ -152,7 +152,7 @@ let p_instruction oc ic =
| Paddic (ir1,ir2,c) -> fprintf oc "{\"Instruction Name\":\"Paddic\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_constant c
| Paddis (ir1,ir2,c) -> fprintf oc "{\"Instruction Name\":\"Paddis\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_constant c
| Paddze (ir1,ir2) -> fprintf oc "{\"Instruction Name\":\"Paddze\",\"Args\":[%a,%a]}" p_ireg ir1 p_ireg ir2
- | Pallocframe (c,i) -> assert false(* Should not occur *)
+ | Pallocframe (c,i,r) -> assert false(* Should not occur *)
| Pand_ (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pand_\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Pandc (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pandc\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Pandi_ (ir1,ir2,c) -> fprintf oc "{\"Instruction Name\":\"Pandi_\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_constant c
@@ -167,6 +167,7 @@ let p_instruction oc ic =
| Pblr -> fprintf oc "{\"Instruction Name\":\"Pblr\",\"Args\":[]}"
| Pbt (cr,l) -> fprintf oc "{\"Instruction Name\":\"Pbt\",\"Args\":[%a,%a]}" p_crbit cr p_label l
| Pbtbl (i,lb) -> fprintf oc "{\"Instruction Name\":\"Pbtl\",\"Args\":[%a%a]}" p_ireg i (p_list_cont p_label) lb
+ | Pcmpb (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pcmpb\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Pcmplw (ir1,ir2) -> fprintf oc "{\"Instruction Name\":\"Pcmplw\",\"Args\":[%a,%a]}" p_ireg ir1 p_ireg ir2
| Pcmplwi (ir,c) -> fprintf oc "{\"Instruction Name\":\"Pcmplwi\",\"Args\":[%a,%a]}" p_ireg ir p_constant c
| Pcmpw (ir1,ir2) -> fprintf oc "{\"Instruction Name\":\"Pcmpw\",\"Args\":[%a,%a]}" p_ireg ir1 p_ireg ir2
@@ -216,6 +217,7 @@ let p_instruction oc ic =
| Pfrsqrte (fr1,fr2) -> fprintf oc "{\"Instruction Name\":\"Pfsqrte\",\"Args\":[%a,%a]}" p_freg fr1 p_freg fr2
| Pfres (fr1,fr2) -> fprintf oc "{\"Instruction Name\":\"Pfres\",\"Args\":[%a,%a]}" p_freg fr1 p_freg fr2
| Pfsel (fr1,fr2,fr3,fr4) -> fprintf oc "{\"Instruction Name\":\"Pfsel\",\"Args\":[%a,%a,%a,%a]}" p_freg fr1 p_freg fr2 p_freg fr3 p_freg fr4
+ | Pisel (ir1,ir2,ir3,cr) -> fprintf oc "{\"Instruction Name\":\"Pisel\",\"Args\":[%a,%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3 p_crbit cr
| Picbi (ir1,ir2) -> fprintf oc "{\"Instruction Name\":\"Picbi\",\"Args\":[%a,%a]}" p_ireg ir1 p_ireg ir2
| Picbtls (n,ir1,ir2) -> fprintf oc "{\"Instruction Name\":\"Picbtls\",\"Args\":[%a,%a,%a]}" p_int_constant n p_ireg ir1 p_ireg ir2
| Pisync -> fprintf oc "{\"Instruction Name\":\"Pisync\",\"Args\":[]}"
@@ -286,7 +288,7 @@ let p_instruction oc ic =
| Pstwx_a (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pstwx\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Pstwux (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pstwux\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Pstwbrx (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pstwbrx\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
- | Pstwcx_ (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pstwc_\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
+ | Pstwcx_ (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Pstwcx_\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Psubfc (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Psubfc\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Psubfe (ir1,ir2,ir3) -> fprintf oc "{\"Instruction Name\":\"Psubfe\",\"Args\":[%a,%a,%a]}" p_ireg ir1 p_ireg ir2 p_ireg ir3
| Psubfze (ir1,ir2) -> fprintf oc "{\"Instruction Name\":\"Psubfe\",\"Args\":[%a,%a]}" p_ireg ir1 p_ireg ir2
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml
index 3e57cdbf..b9fe1d7f 100644
--- a/powerpc/Asmexpand.ml
+++ b/powerpc/Asmexpand.ml
@@ -276,6 +276,9 @@ let expand_builtin_vstore chunk args =
assert false
(* Handling of varargs *)
+let linkregister_offset = ref Int.zero
+
+let retaddr_offset = ref Int.zero
let current_function_stacksize = ref 0l
@@ -324,56 +327,6 @@ let expand_builtin_va_start r =
let expand_int64_arith conflict rl fn =
if conflict then (fn GPR0; emit (Pmr(rl, GPR0))) else fn rl
-(* Handling of cache instructions *)
-
-(* Auxiliary function to generate address for the cache function *)
-let expand_builtin_cache_common addr f =
- let add = match addr with
- | BA (IR a1) -> a1
- | BA_addrstack ofs ->
- emit_addimm GPR11 GPR1 ofs;
- GPR11
- | BA_addrglobal(id, ofs) ->
- if symbol_is_small_data id ofs then begin
- emit (Paddi (GPR11, GPR0, Csymbol_sda(id, ofs)));
- GPR11
- end else if symbol_is_rel_data id ofs then begin
- emit (Paddis(GPR11, GPR0, Csymbol_rel_high(id, ofs)));
- emit (Paddi(GPR11, GPR11, Csymbol_rel_low(id, ofs)));
- GPR11
- end else begin
- emit (Paddis(GPR11, GPR0, Csymbol_high(id, ofs)));
- emit (Paddi (GPR11, GPR11, Csymbol_low(id, ofs)));
- GPR11
- end
- | _ -> raise (Error "Argument is not an address") in
- f add
-
-let expand_builtin_prefetch addr rw loc =
- if not ((loc >= _0) && (loc <= _2)) then
- raise (Error "the last argument of __builtin_prefetch must be a constant between 0 and 2");
- let emit_prefetch_instr addr =
- if Int.eq rw _0 then begin
- emit (Pdcbt (loc,GPR0,addr));
- end else if Int.eq rw _1 then begin
- emit (Pdcbtst (loc,GPR0,addr));
- end else
- raise (Error "the second argument of __builtin_prefetch must be either 0 or 1")
- in
- expand_builtin_cache_common addr emit_prefetch_instr
-
-let expand_builtin_dcbtls addr loc =
- if not ((loc == _0) || (loc = _2)) then
- raise (Error "the second argument of __builtin_dcbtls must be a constant between 0 and 2");
- let emit_inst addr = emit (Pdcbtls (loc,GPR0,addr)) in
- expand_builtin_cache_common addr emit_inst
-
-let expand_builtin_icbtls addr loc =
- if not ((loc == _0) || (loc = _2)) then
- raise (Error "the second argument of __builtin_icbtls must be a constant between 0 and 2");
- let emit_inst addr = emit (Picbtls (loc,GPR0,addr)) in
- expand_builtin_cache_common addr emit_inst
-
(* Handling of compiler-inlined builtins *)
let expand_builtin_inline name args res =
@@ -386,6 +339,8 @@ let expand_builtin_inline name args res =
emit (Pmulhwu(res, a1, a2))
| "__builtin_clz", [BA(IR a1)], BR(IR res) ->
emit (Pcntlzw(res, a1))
+ | "__builtin_cmpb", [BA(IR a1); BA(IR a2)], BR(IR res) ->
+ emit (Pcmpb (res,a1,a2))
| ("__builtin_bswap" | "__builtin_bswap32"), [BA(IR a1)], BR(IR res) ->
emit (Pstwu(a1, Cint _m8, GPR1));
emit (Pcfi_adjust _8);
@@ -468,7 +423,7 @@ let expand_builtin_inline name args res =
emit (Plwsync)
| "__builtin_mbar", [BA_int mo], _ ->
if not (mo = _0 || mo = _1) then
- raise (Error "the argument of __builtin_mbar must be either 0 or 1");
+ raise (Error "the argument of __builtin_mbar must be 0 or 1");
emit (Pmbar mo)
| "__builin_mbar",_, _ ->
raise (Error "the argument of __builtin_mbar must be a constant");
@@ -484,16 +439,27 @@ let expand_builtin_inline name args res =
emit (Pdcbi (GPR0,a1))
| "__builtin_icbi", [BA(IR a1)],_ ->
emit (Picbi(GPR0,a1))
- | "__builtin_dcbtls", [a; BA_int loc],_ ->
- expand_builtin_dcbtls a loc
+ | "__builtin_dcbtls", [BA (IR a1); BA_int loc],_ ->
+ if not ((Int.eq loc _0) || (Int.eq loc _2)) then
+ raise (Error "the second argument of __builtin_dcbtls must be 0 or 2");
+ emit (Pdcbtls (loc,GPR0,a1))
| "__builtin_dcbtls",_,_ ->
raise (Error "the second argument of __builtin_dcbtls must be a constant")
- | "__builtin_icbtls", [a; BA_int loc],_ ->
- expand_builtin_icbtls a loc
+ | "__builtin_icbtls", [BA (IR a1); BA_int loc],_ ->
+ if not ((Int.eq loc _0) || (Int.eq loc _2)) then
+ raise (Error "the second argument of __builtin_icbtls must be 0 or 2");
+ emit (Picbtls (loc,GPR0,a1))
| "__builtin_icbtls",_,_ ->
raise (Error "the second argument of __builtin_icbtls must be a constant")
- | "__builtin_prefetch" , [a1 ;BA_int rw; BA_int loc],_ ->
- expand_builtin_prefetch a1 rw loc
+ | "__builtin_prefetch" , [BA (IR a1) ;BA_int rw; BA_int loc],_ ->
+ if not (Int.ltu loc _4) then
+ raise (Error "the last argument of __builtin_prefetch must be 0, 1 or 2");
+ if Int.eq rw _0 then begin
+ emit (Pdcbt (loc,GPR0,a1));
+ end else if Int.eq rw _1 then begin
+ emit (Pdcbtst (loc,GPR0,a1));
+ end else
+ raise (Error "the second argument of __builtin_prefetch must be 0 or 1")
| "__builtin_prefetch" ,_,_ ->
raise (Error "the second and third argument of __builtin_prefetch must be a constant")
| "__builtin_dcbz",[BA (IR a1)],_ ->
@@ -507,6 +473,20 @@ let expand_builtin_inline name args res =
emit (Pmtspr(n, a1))
| "__builtin_set_spr", _, _ ->
raise (Error "the first argument of __builtin_set_spr must be a constant")
+ (* Frame and return address *)
+ | "__builtin_call_frame", _,BR (IR res) ->
+ let sz = !current_function_stacksize
+ and ofs = !linkregister_offset in
+ if sz < 0x8000l then
+ emit (Paddi(res, GPR1, Cint(coqint_of_camlint sz)))
+ else
+ emit (Plwz(res, Cint ofs, GPR1))
+ | "__builtin_return_address",_,BR (IR res) ->
+ emit (Plwz (res, Cint! retaddr_offset,GPR1))
+ (* isel *)
+ | "__builtin_isel", [BA (IR a1); BA (IR a2); BA (IR a3)],BR (IR res) ->
+ emit (Pcmpwi (a1,Cint (Int.zero)));
+ emit (Pisel (res,a3,a2,CRbit_2))
(* Catch-all *)
| _ ->
raise (Error ("unrecognized builtin " ^ name))
@@ -534,7 +514,7 @@ let num_crbit = function
let expand_instruction instr =
match instr with
- | Pallocframe(sz, ofs) ->
+ | Pallocframe(sz, ofs,retofs) ->
let variadic = (!current_function).fn_sig.sig_cc.cc_vararg in
let sz = camlint_of_coqint sz in
assert (ofs = Int.zero);
@@ -553,7 +533,9 @@ let expand_instruction instr =
{sig_args = []; sig_res = None; sig_cc = cc_default}));
emit (Pmtlr GPR0)
end;
- current_function_stacksize := sz
+ current_function_stacksize := sz;
+ linkregister_offset := ofs;
+ retaddr_offset := retofs
| Pbctr sg | Pbctrl sg | Pbl(_, sg) | Pbs(_, sg) ->
set_cr6 sg;
emit instr
diff --git a/powerpc/Asmgen.v b/powerpc/Asmgen.v
index 541fe7c6..db3b7028 100644
--- a/powerpc/Asmgen.v
+++ b/powerpc/Asmgen.v
@@ -711,7 +711,7 @@ Definition transl_code' (f: Mach.function) (il: list Mach.instruction) (it1p: bo
Definition transl_function (f: Mach.function) :=
do c <- transl_code' f f.(Mach.fn_code) false;
OK (mkfunction f.(Mach.fn_sig)
- (Pallocframe f.(fn_stacksize) f.(fn_link_ofs) ::
+ (Pallocframe f.(fn_stacksize) f.(fn_link_ofs) f.(fn_retaddr_ofs) ::
Pmflr GPR0 ::
Pstw GPR0 (Cint f.(fn_retaddr_ofs)) GPR1 ::
Pcfi_rel_offset f.(fn_retaddr_ofs) :: c)).
diff --git a/powerpc/CBuiltins.ml b/powerpc/CBuiltins.ml
index e18fdb2d..1bb8c6f7 100644
--- a/powerpc/CBuiltins.ml
+++ b/powerpc/CBuiltins.ml
@@ -36,6 +36,8 @@ let builtins = {
(TInt(IUInt, []), [TInt(IUInt, [])], false);
"__builtin_bswap16",
(TInt(IUShort, []), [TInt(IUShort, [])], false);
+ "__builtin_cmpb",
+ (TInt (IUInt, []), [TInt(IUInt, []);TInt(IUInt, [])], false);
(* Float arithmetic *)
"__builtin_fmadd",
(TFloat(FDouble, []),
@@ -108,7 +110,15 @@ let builtins = {
"__builtin_get_spr",
(TInt(IUInt, []), [TInt(IInt, [])], false);
"__builtin_set_spr",
- (TVoid [], [TInt(IInt, []); TInt(IUInt, [])], false)
+ (TVoid [], [TInt(IInt, []); TInt(IUInt, [])], false);
+ (* Frame and return address *)
+ "__builtin_call_frame",
+ (TPtr (TVoid [],[]),[],false);
+ "__builtin_return_address",
+ (TPtr (TVoid [],[]),[],false);
+ (* isel *)
+ "__builtin_isel",
+ (TInt (IInt, []),[TInt(IBool, []);TInt(IInt, []);TInt(IInt, [])],false)
]
}
diff --git a/powerpc/Machregs.v b/powerpc/Machregs.v
index 402f07d1..a2017dca 100644
--- a/powerpc/Machregs.v
+++ b/powerpc/Machregs.v
@@ -217,9 +217,9 @@ Definition builtin_constraints (ef: external_function) :
| EF_builtin id sg =>
if ident_eq id builtin_get_spr then OK_const :: nil
else if ident_eq id builtin_set_spr then OK_const :: OK_default :: nil
- else if ident_eq id builtin_prefetch then OK_addrany :: OK_const :: OK_const :: nil
- else if ident_eq id builtin_dcbtls then OK_addrany::OK_const::nil
- else if ident_eq id builtin_icbtls then OK_addrany::OK_const::nil
+ else if ident_eq id builtin_prefetch then OK_default :: OK_const :: OK_const :: nil
+ else if ident_eq id builtin_dcbtls then OK_default::OK_const::nil
+ else if ident_eq id builtin_icbtls then OK_default::OK_const::nil
else if ident_eq id builtin_mbar then OK_const::nil
else nil
| EF_vload _ => OK_addrany :: nil
diff --git a/powerpc/TargetPrinter.ml b/powerpc/TargetPrinter.ml
index c126f641..58117ee7 100644
--- a/powerpc/TargetPrinter.ml
+++ b/powerpc/TargetPrinter.ml
@@ -384,7 +384,7 @@ module Target (System : SYSTEM):TARGET =
fprintf oc " addis %a, %a, %a\n" ireg r1 ireg_or_zero r2 constant c
| Paddze(r1, r2) ->
fprintf oc " addze %a, %a\n" ireg r1 ireg r2
- | Pallocframe(sz, ofs) ->
+ | Pallocframe(sz, ofs, _) ->
assert false
| Pand_(r1, r2, r3) ->
fprintf oc " and. %a, %a, %a\n" ireg r1 ireg r2 ireg r3
@@ -443,6 +443,8 @@ module Target (System : SYSTEM):TARGET =
fprintf oc " bctr\n";
jumptables := (lbl, tbl) :: !jumptables;
fprintf oc "%s end pseudoinstr btbl\n" comment
+ | Pcmpb (r1, r2, r3) ->
+ fprintf oc " cmpb %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Pcmplw(r1, r2) ->
fprintf oc " cmplw %a, %a, %a\n" creg 0 ireg r1 ireg r2
| Pcmplwi(r1, c) ->
@@ -537,6 +539,8 @@ module Target (System : SYSTEM):TARGET =
fprintf oc " fres %a, %a\n" freg r1 freg r2
| Pfsel(r1, r2, r3, r4) ->
fprintf oc " fsel %a, %a, %a, %a\n" freg r1 freg r2 freg r3 freg r4
+ | Pisel (r1,r2,r3,cr) ->
+ fprintf oc " isel %a, %a, %a, %a\n" ireg r1 ireg r2 ireg r3 crbit cr
| Picbi (r1,r2) ->
fprintf oc " icbi %a,%a\n" ireg r1 ireg r2
| Picbtls (n,r1,r2) ->