aboutsummaryrefslogtreecommitdiff
path: root/src/Assembly/QhasmCommon.v
blob: f213dc9a41347a02ef3d8e8421eeec9f63bfac9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
Require Export String List NPeano NArith.
Require Export Bedrock.Word.

(* A formalization of x86 qhasm *)
Definition Label := nat.
Definition Index (limit: nat) := {x: nat | (x < limit)%nat}.
Definition Invert := bool.

(* Sugar and Tactics *)

Definition convert {A B: Type} (x: A) (H: A = B): B :=
  eq_rect A (fun B0 : Type => B0) x B H.

Notation "'always' A" := (fun _ => A) (at level 90) : state_scope.
Notation "'cast' e" := (convert e _) (at level 20) : state_scope.
Notation "'lift' e" := (exist _ e _) (at level 20) : state_scope.
Notation "'contra'" := (False_rec _ _) : state_scope.

Obligation Tactic := abstract intuition.

(* Asm Types *)
Inductive ISize: nat -> Type :=
  | I32: ISize 32
  | I64: ISize 64.

Inductive IConst: nat -> Type :=
  | constInt32: word 32 -> IConst 32
  | constInt64: word 64 -> IConst 64.

Inductive IReg: nat -> Type :=
  | regInt32: nat -> IReg 32
  | regInt64: nat -> IReg 64.

Inductive Stack: nat -> Type :=
  | stack32: nat -> Stack 32
  | stack64: nat -> Stack 64
  | stack128: nat -> Stack 128.

Definition CarryState := option bool.

(* Assignments *)
Inductive Assignment : Type :=
  | ARegStackInt: forall n, IReg n -> Stack n -> Assignment
  | AStackRegInt: forall n, Stack n -> IReg n -> Assignment
  | ARegRegInt: forall n, IReg n -> IReg n -> Assignment
  | AConstInt: forall n, IReg n -> IConst n -> Assignment
  | AIndex: forall n m, IReg n -> Stack m -> Index (m/n)%nat -> Assignment
  | APtr: forall n, IReg 32 -> Stack n -> Assignment.

Hint Constructors Assignment.

(* Operations *)

Inductive IntOp :=
  | IPlus: IntOp | IMinus: IntOp
  | IXor: IntOp  | IAnd: IntOp | IOr: IntOp.

Inductive DualOp :=
  | IMult: DualOp.

Inductive RotOp :=
  | Shl: RotOp | Shr: RotOp.

Inductive Operation :=
  | IOpConst: forall n, IntOp -> IReg n -> IConst n -> Operation
  | IOpReg: forall n, IntOp -> IReg n -> IReg n -> Operation
  | DOpReg: forall n, DualOp -> IReg n -> IReg n -> option (IReg n) -> Operation
  | OpRot: forall n, RotOp -> IReg n -> Index n -> Operation.

Hint Constructors Operation.

(* Control Flow *)

Inductive TestOp :=
  | TEq: TestOp   | TLt: TestOp  | TLe: TestOp
  | TGt: TestOp   | TGe: TestOp.

Inductive Conditional :=
  | TestTrue: Conditional
  | TestFalse: Conditional
  | TestInt: forall n, TestOp -> IReg n -> IReg n -> Conditional.

Hint Constructors Conditional.

(* Reg, Stack, Const Utilities *)

Definition getIRegWords {n} (x: IReg n) :=
  match x with
  | regInt32 loc => 1
  | regInt64 loc => 2
  end.

Definition getStackWords {n} (x: Stack n) :=
  match x with
  | stack32 loc => 1
  | stack64 loc => 2
  | stack128 loc => 4
  end.

Definition getIConstValue {n} (x: IConst n): nat :=
  match x with
  | constInt32 v => wordToNat v
  | constInt64 v => wordToNat v
  end.

Definition getIRegIndex {n} (x: IReg n): nat :=
  match x with
  | regInt32 loc => loc
  | regInt64 loc => loc
  end.

Definition getStackIndex {n} (x: Stack n): nat :=
  match x with
  | stack32 loc => loc
  | stack64 loc => loc
  | stack128 loc => loc
  end.

(* For register allocation checking *)
Definition intRegCount (base: nat): nat :=
  match base with
  | 32 => 7
  | 64 => 8
  | _ => 0
  end.