Library compcert.x86.Machregs
Require Import String.
Require Import Coqlib.
Require Import Decidableplus.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Op.
Machine registers
- Integer registers that can be allocated to RTL pseudo-registers.
- Floating-point registers that can be allocated to RTL pseudo-registers.
- The special FP0 register denoting the top of the X87 float stack.
Allocatable integer regs
Allocatable float regs
Special float reg
| FP0.
Lemma mreg_eq: ∀ (r1 r2: mreg), {r1 = r2} + {r1 ≠ r2}.
Proof. decide equality. Defined.
Global Opaque mreg_eq.
Definition all_mregs :=
AX :: BX :: CX :: DX :: SI :: DI :: BP
:: R8 :: R9 :: R10 :: R11 :: R12 :: R13 :: R14 :: R15
:: X0 :: X1 :: X2 :: X3 :: X4 :: X5 :: X6 :: X7
:: X8 :: X9 :: X10 :: X11 :: X12 :: X13 :: X14 :: X15
:: FP0 :: nil.
Lemma all_mregs_complete:
∀ (r: mreg), In r all_mregs.
Proof.
assert (∀ r, proj_sumbool (In_dec mreg_eq r all_mregs) = true) by (destruct r; reflexivity).
intros. specialize (H r). InvBooleans. auto.
Qed.
Instance Decidable_eq_mreg : ∀ (x y: mreg), Decidable (eq x y) := Decidable_eq mreg_eq.
Instance Finite_mreg : Finite mreg := {
Finite_elements := all_mregs;
Finite_elements_spec := all_mregs_complete
}.
Definition mreg_type (r: mreg): typ :=
match r with
| AX | BX | CX | DX | SI | DI | BP ⇒ if Archi.ptr64 then Tany64 else Tany32
| R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15 ⇒ Tany64
| X0 | X1 | X2 | X3 | X4 | X5 | X6 | X7 ⇒ Tany64
| X8 | X9 | X10 | X11 | X12 | X13 | X14 | X15 ⇒ Tany64
| FP0 ⇒ Tany64
end.
Local Open Scope positive_scope.
Module IndexedMreg <: INDEXED_TYPE.
Definition t := mreg.
Definition eq := mreg_eq.
Definition index (r: mreg): positive :=
match r with
| AX ⇒ 1 | BX ⇒ 2 | CX ⇒ 3 | DX ⇒ 4 | SI ⇒ 5 | DI ⇒ 6 | BP ⇒ 7
| R8 ⇒ 8 | R9 ⇒ 9 | R10 ⇒ 10 | R11 ⇒ 11 | R12 ⇒ 12 | R13 ⇒ 13 | R14 ⇒ 14 | R15 ⇒ 15
| X0 ⇒ 16 | X1 ⇒ 17 | X2 ⇒ 18 | X3 ⇒ 19 | X4 ⇒ 20 | X5 ⇒ 21 | X6 ⇒ 22 | X7 ⇒ 23
| X8 ⇒ 24 | X9 ⇒ 25 | X10 ⇒ 26 | X11 ⇒ 27 | X12 ⇒ 28 | X13 ⇒ 29 | X14 ⇒ 30 | X15 ⇒ 31
| FP0 ⇒ 32
end.
Lemma index_inj:
∀ r1 r2, index r1 = index r2 → r1 = r2.
Proof.
decide_goal.
Qed.
End IndexedMreg.
Definition is_stack_reg (r: mreg) : bool :=
match r with FP0 ⇒ true | _ ⇒ false end.
Lemma mreg_eq: ∀ (r1 r2: mreg), {r1 = r2} + {r1 ≠ r2}.
Proof. decide equality. Defined.
Global Opaque mreg_eq.
Definition all_mregs :=
AX :: BX :: CX :: DX :: SI :: DI :: BP
:: R8 :: R9 :: R10 :: R11 :: R12 :: R13 :: R14 :: R15
:: X0 :: X1 :: X2 :: X3 :: X4 :: X5 :: X6 :: X7
:: X8 :: X9 :: X10 :: X11 :: X12 :: X13 :: X14 :: X15
:: FP0 :: nil.
Lemma all_mregs_complete:
∀ (r: mreg), In r all_mregs.
Proof.
assert (∀ r, proj_sumbool (In_dec mreg_eq r all_mregs) = true) by (destruct r; reflexivity).
intros. specialize (H r). InvBooleans. auto.
Qed.
Instance Decidable_eq_mreg : ∀ (x y: mreg), Decidable (eq x y) := Decidable_eq mreg_eq.
Instance Finite_mreg : Finite mreg := {
Finite_elements := all_mregs;
Finite_elements_spec := all_mregs_complete
}.
Definition mreg_type (r: mreg): typ :=
match r with
| AX | BX | CX | DX | SI | DI | BP ⇒ if Archi.ptr64 then Tany64 else Tany32
| R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15 ⇒ Tany64
| X0 | X1 | X2 | X3 | X4 | X5 | X6 | X7 ⇒ Tany64
| X8 | X9 | X10 | X11 | X12 | X13 | X14 | X15 ⇒ Tany64
| FP0 ⇒ Tany64
end.
Local Open Scope positive_scope.
Module IndexedMreg <: INDEXED_TYPE.
Definition t := mreg.
Definition eq := mreg_eq.
Definition index (r: mreg): positive :=
match r with
| AX ⇒ 1 | BX ⇒ 2 | CX ⇒ 3 | DX ⇒ 4 | SI ⇒ 5 | DI ⇒ 6 | BP ⇒ 7
| R8 ⇒ 8 | R9 ⇒ 9 | R10 ⇒ 10 | R11 ⇒ 11 | R12 ⇒ 12 | R13 ⇒ 13 | R14 ⇒ 14 | R15 ⇒ 15
| X0 ⇒ 16 | X1 ⇒ 17 | X2 ⇒ 18 | X3 ⇒ 19 | X4 ⇒ 20 | X5 ⇒ 21 | X6 ⇒ 22 | X7 ⇒ 23
| X8 ⇒ 24 | X9 ⇒ 25 | X10 ⇒ 26 | X11 ⇒ 27 | X12 ⇒ 28 | X13 ⇒ 29 | X14 ⇒ 30 | X15 ⇒ 31
| FP0 ⇒ 32
end.
Lemma index_inj:
∀ r1 r2, index r1 = index r2 → r1 = r2.
Proof.
decide_goal.
Qed.
End IndexedMreg.
Definition is_stack_reg (r: mreg) : bool :=
match r with FP0 ⇒ true | _ ⇒ false end.
Local Open Scope string_scope.
Definition register_names :=
("RAX", AX) :: ("RBX", BX) :: ("RCX", CX) :: ("RDX", DX) ::
("RSI", SI) :: ("RDI", DI) :: ("RBP", BP) ::
("EAX", AX) :: ("EBX", BX) :: ("ECX", CX) :: ("EDX", DX) ::
("ESI", SI) :: ("EDI", DI) :: ("EBP", BP) ::
("R8", R8) :: ("R9", R9) :: ("R10", R10) :: ("R11", R11) ::
("R12", R12) :: ("R13", R13) :: ("R14", R14) :: ("R15", R15) ::
("XMM0", X0) :: ("XMM1", X1) :: ("XMM2", X2) :: ("XMM3", X3) ::
("XMM4", X4) :: ("XMM5", X5) :: ("XMM6", X6) :: ("XMM7", X7) ::
("XMM8", X8) :: ("XMM9", X9) :: ("XMM10", X10) :: ("XMM11", X11) ::
("XMM12", X12) :: ("XMM13", X13) :: ("XMM14", X14) :: ("XMM15", X15) ::
("ST0", FP0) :: nil.
Definition register_by_name (s: string) : option mreg :=
let fix assoc (l: list (string × mreg)) : option mreg :=
match l with
| nil ⇒ None
| (s1, r1) :: l' ⇒ if string_dec s s1 then Some r1 else assoc l'
end
in assoc register_names.
Definition destroyed_by_op (op: operation): list mreg :=
match op with
| Ocast8signed | Ocast8unsigned ⇒ AX :: nil
| Omulhs ⇒ AX :: DX :: nil
| Omulhu ⇒ AX :: DX :: nil
| Odiv ⇒ AX :: DX :: nil
| Odivu ⇒ AX :: DX :: nil
| Omod ⇒ AX :: DX :: nil
| Omodu ⇒ AX :: DX :: nil
| Oshrximm _ ⇒ CX :: nil
| Omullhs ⇒ AX :: DX :: nil
| Omullhu ⇒ AX :: DX :: nil
| Odivl ⇒ AX :: DX :: nil
| Odivlu ⇒ AX :: DX :: nil
| Omodl ⇒ AX :: DX :: nil
| Omodlu ⇒ AX :: DX :: nil
| Oshrxlimm _ ⇒ DX :: nil
| Ocmp _ ⇒ AX :: CX :: nil
| _ ⇒ nil
end.
Definition destroyed_by_load (chunk: memory_chunk) (addr: addressing): list mreg :=
nil.
Definition destroyed_by_store (chunk: memory_chunk) (addr: addressing): list mreg :=
match chunk with
| Mint8signed | Mint8unsigned ⇒ if Archi.ptr64 then nil else AX :: CX :: nil
| _ ⇒ nil
end.
Definition destroyed_by_cond (cond: condition): list mreg :=
nil.
Definition destroyed_by_jumptable: list mreg :=
AX :: DX :: nil.
Fixpoint destroyed_by_clobber (cl: list string): list mreg :=
match cl with
| nil ⇒ nil
| c1 :: cl ⇒
match register_by_name c1 with
| Some r ⇒ r :: destroyed_by_clobber cl
| None ⇒ destroyed_by_clobber cl
end
end.
Definition destroyed_by_builtin (ef: external_function): list mreg :=
match ef with
| EF_memcpy sz al ⇒
if zle sz 32 then CX :: X7 :: nil else CX :: SI :: DI :: nil
| EF_vstore (Mint8unsigned|Mint8signed) ⇒
if Archi.ptr64 then nil else AX :: CX :: nil
| EF_builtin name sg ⇒
if string_dec name "__builtin_va_start" then AX :: nil
else if string_dec name "__builtin_write16_reversed"
|| string_dec name "__builtin_write32_reversed"
then CX :: DX :: nil
else nil
| EF_inline_asm txt sg clob ⇒ destroyed_by_clobber clob
| _ ⇒ nil
end.
Definition destroyed_at_function_entry: list mreg :=
AX :: FP0 :: nil.
Definition destroyed_by_setstack (ty: typ): list mreg :=
match ty with
| Tfloat | Tsingle ⇒ FP0 :: nil
| _ ⇒ nil
end.
Definition destroyed_at_indirect_call: list mreg :=
AX :: nil.
Definition temp_for_parent_frame: mreg :=
AX.
Definition mregs_for_operation (op: operation): list (option mreg) × option mreg :=
match op with
| Omulhs ⇒ (Some AX :: None :: nil, Some DX)
| Omulhu ⇒ (Some AX :: None :: nil, Some DX)
| Odiv ⇒ (Some AX :: Some CX :: nil, Some AX)
| Odivu ⇒ (Some AX :: Some CX :: nil, Some AX)
| Omod ⇒ (Some AX :: Some CX :: nil, Some DX)
| Omodu ⇒ (Some AX :: Some CX :: nil, Some DX)
| Oshl ⇒ (None :: Some CX :: nil, None)
| Oshr ⇒ (None :: Some CX :: nil, None)
| Oshru ⇒ (None :: Some CX :: nil, None)
| Oshrximm _ ⇒ (Some AX :: nil, Some AX)
| Omullhs ⇒ (Some AX :: None :: nil, Some DX)
| Omullhu ⇒ (Some AX :: None :: nil, Some DX)
| Odivl ⇒ (Some AX :: Some CX :: nil, Some AX)
| Odivlu ⇒ (Some AX :: Some CX :: nil, Some AX)
| Omodl ⇒ (Some AX :: Some CX :: nil, Some DX)
| Omodlu ⇒ (Some AX :: Some CX :: nil, Some DX)
| Oshll ⇒ (None :: Some CX :: nil, None)
| Oshrl ⇒ (None :: Some CX :: nil, None)
| Oshrlu ⇒ (None :: Some CX :: nil, None)
| Oshrxlimm _ ⇒ (Some AX :: nil, Some AX)
| _ ⇒ (nil, None)
end.
Definition mregs_for_builtin (ef: external_function): list (option mreg) × list (option mreg) :=
match ef with
| EF_memcpy sz al ⇒
if zle sz 32 then (Some AX :: Some DX :: nil, nil) else (Some DI :: Some SI :: nil, nil)
| EF_builtin name sg ⇒
if string_dec name "__builtin_negl" then
(Some DX :: Some AX :: nil, Some DX :: Some AX :: nil)
else if string_dec name "__builtin_addl"
|| string_dec name "__builtin_subl" then
(Some DX :: Some AX :: Some CX :: Some BX :: nil, Some DX :: Some AX :: nil)
else if string_dec name "__builtin_mull" then
(Some AX :: Some DX :: nil, Some DX :: Some AX :: nil)
else if string_dec name "__builtin_va_start" then
(Some DX :: nil, nil)
else if (negb Archi.ptr64) && string_dec name "__builtin_bswap64" then
(Some AX :: Some DX :: nil, Some DX :: Some AX :: nil)
else
(nil, nil)
| _ ⇒ (nil, nil)
end.
Global Opaque
destroyed_by_op destroyed_by_load destroyed_by_store
destroyed_by_cond destroyed_by_jumptable destroyed_by_builtin
destroyed_by_setstack destroyed_at_function_entry temp_for_parent_frame
mregs_for_operation mregs_for_builtin.
Two-address operations. Return true if the first argument and
the result must be in the same location *and* are unconstrained
by mregs_for_operation.
Definition two_address_op (op: operation) : bool :=
match op with
| Omove ⇒ false
| Ointconst _ ⇒ false
| Olongconst _ ⇒ false
| Ofloatconst _ ⇒ false
| Osingleconst _ ⇒ false
| Oindirectsymbol _ ⇒ false
| Ocast8signed ⇒ false
| Ocast8unsigned ⇒ false
| Ocast16signed ⇒ false
| Ocast16unsigned ⇒ false
| Oneg ⇒ true
| Osub ⇒ true
| Omul ⇒ true
| Omulimm _ ⇒ true
| Omulhs ⇒ false
| Omulhu ⇒ false
| Odiv ⇒ false
| Odivu ⇒ false
| Omod ⇒ false
| Omodu ⇒ false
| Oand ⇒ true
| Oandimm _ ⇒ true
| Oor ⇒ true
| Oorimm _ ⇒ true
| Oxor ⇒ true
| Oxorimm _ ⇒ true
| Onot ⇒ true
| Oshl ⇒ true
| Oshlimm _ ⇒ true
| Oshr ⇒ true
| Oshrimm _ ⇒ true
| Oshrximm _ ⇒ false
| Oshru ⇒ true
| Oshruimm _ ⇒ true
| Ororimm _ ⇒ true
| Oshldimm _ ⇒ true
| Olea addr ⇒ false
| Omakelong ⇒ true
| Olowlong ⇒ true
| Ohighlong ⇒ true
| Ocast32signed ⇒ false
| Ocast32unsigned ⇒ false
| Onegl ⇒ true
| Oaddlimm _ ⇒ true
| Osubl ⇒ true
| Omull ⇒ true
| Omullimm _ ⇒ true
| Omullhs ⇒ false
| Omullhu ⇒ false
| Odivl ⇒ false
| Odivlu ⇒ false
| Omodl ⇒ false
| Omodlu ⇒ false
| Oandl ⇒ true
| Oandlimm _ ⇒ true
| Oorl ⇒ true
| Oorlimm _ ⇒ true
| Oxorl ⇒ true
| Oxorlimm _ ⇒ true
| Onotl ⇒ true
| Oshll ⇒ true
| Oshllimm _ ⇒ true
| Oshrl ⇒ true
| Oshrlimm _ ⇒ true
| Oshrxlimm _ ⇒ false
| Oshrlu ⇒ true
| Oshrluimm _ ⇒ true
| Ororlimm _ ⇒ true
| Oleal addr ⇒ false
| Onegf ⇒ true
| Oabsf ⇒ true
| Oaddf ⇒ true
| Osubf ⇒ true
| Omulf ⇒ true
| Odivf ⇒ true
| Onegfs ⇒ true
| Oabsfs ⇒ true
| Oaddfs ⇒ true
| Osubfs ⇒ true
| Omulfs ⇒ true
| Odivfs ⇒ true
| Osingleoffloat ⇒ false
| Ofloatofsingle ⇒ false
| Ointoffloat ⇒ false
| Ofloatofint ⇒ false
| Ointofsingle ⇒ false
| Osingleofint ⇒ false
| Olongoffloat ⇒ false
| Ofloatoflong ⇒ false
| Olongofsingle ⇒ false
| Osingleoflong ⇒ false
| Ocmp c ⇒ false
end.
Definition builtin_constraints (ef: external_function) :
list builtin_arg_constraint :=
match ef with
| EF_vload _ ⇒ OK_addrany :: nil
| EF_vstore _ ⇒ OK_addrany :: OK_default :: nil
| EF_memcpy _ _ ⇒ OK_addrany :: OK_addrany :: nil
| EF_annot txt targs ⇒ map (fun _ ⇒ OK_all) targs
| EF_debug kind txt targs ⇒ map (fun _ ⇒ OK_all) targs
| _ ⇒ nil
end.