1--  Mcode back-end for ortho - X86 common definitions.
2--  Copyright (C) 2006 Tristan Gingold
3--
4--  This program is free software: you can redistribute it and/or modify
5--  it under the terms of the GNU General Public License as published by
6--  the Free Software Foundation, either version 2 of the License, or
7--  (at your option) any later version.
8--
9--  This program is distributed in the hope that it will be useful,
10--  but WITHOUT ANY WARRANTY; without even the implied warranty of
11--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12--  GNU General Public License for more details.
13--
14--  You should have received a copy of the GNU General Public License
15--  along with this program.  If not, see <gnu.org/licenses>.
16
17package Ortho_Code.X86 is
18   --  Registers.
19   R_Nil : constant O_Reg := 0;
20
21   --  Not a value.  Used for statements.
22   R_None : constant O_Reg := 1;
23
24   --  Memory.
25   R_Mem : constant O_Reg := 2;
26
27   --  Spilled out.
28   R_Spill : constant O_Reg := 3;
29
30   --  Register or memory.
31   --  THis can only be requested.
32   R_Rm : constant O_Reg := 48;
33
34   --  Immediat
35   R_Imm : constant O_Reg := 49;
36
37   --  Immediat, register or memory.
38   --  This can be requested.
39   R_Irm : constant O_Reg := 50;
40
41   --  Immediat or register.
42   --  This can be requested.
43   R_Ir : constant O_Reg := 51;
44
45   --  BASE + OFFSET
46   R_B_Off : constant O_Reg := 52;
47
48   --  BASE+INDEX*SCALE+OFFSET
49   --  This can be requested.
50   R_Sib : constant O_Reg := 53;
51
52   --  INDEX*SCALE + OFFSET
53   --  This can be requested.
54   R_I_Off : constant O_Reg := 54;
55
56   --  BASE + INDEX*SCALE
57   R_B_I : constant O_Reg := 55;
58
59   --  INDEX*SCALE
60   R_I : constant O_Reg := 56;
61
62   subtype Regs_Imm32 is O_Reg range R_Irm .. R_I_Off;
63
64   R_Any8  : constant O_Reg := 5;
65   R_Any32 : constant O_Reg := 6;
66   R_Any64 : constant O_Reg := 7;
67   R_Ax : constant O_Reg := 8;
68   R_Cx : constant O_Reg := 9;
69   R_Dx : constant O_Reg := 10;
70   R_Bx : constant O_Reg := 11;
71   R_Sp : constant O_Reg := 12;
72   R_Bp : constant O_Reg := 13;
73   R_Si : constant O_Reg := 14;
74   R_Di : constant O_Reg := 15;
75   R_R8 : constant O_Reg := 16;
76   R_R9 : constant O_Reg := 17;
77   R_R10 : constant O_Reg := 18;
78   R_R11 : constant O_Reg := 19;
79   R_R12 : constant O_Reg := 20;
80   R_R13 : constant O_Reg := 21;
81   R_R14 : constant O_Reg := 22;
82   R_R15 : constant O_Reg := 23;
83
84   subtype Regs_R8 is O_Reg range R_Ax .. R_Bx;
85   subtype Regs_R32 is O_Reg range R_Ax .. R_Di;
86   subtype Regs_R64 is O_Reg range R_Ax .. R_R15;
87   subtype Regs_R8_R15 is O_Reg range R_R8 .. R_R15;
88
89   R_St0 : constant O_Reg := 24;
90   R_St1 : constant O_Reg := 25;
91   R_St2 : constant O_Reg := 26;
92   R_St3 : constant O_Reg := 27;
93   R_St4 : constant O_Reg := 28;
94   R_St5 : constant O_Reg := 29;
95   R_St6 : constant O_Reg := 30;
96   R_St7 : constant O_Reg := 31;
97   --R_Any_Fp : constant O_Reg := 24;
98
99   subtype Regs_Fp is O_Reg range R_St0 .. R_St7;
100
101   --  Any condition register.
102   R_Any_Cc : constant O_Reg := 32;
103   R_Ov : constant O_Reg := 32;
104   R_No : constant O_Reg := 33;
105   R_Ult : constant O_Reg := 34;
106   R_Uge : constant O_Reg := 35;
107   R_Eq : constant O_Reg := 36;
108   R_Ne : constant O_Reg := 37;
109   R_Ule : constant O_Reg := 38;
110   R_Ugt : constant O_Reg := 39;
111   R_Slt : constant O_Reg := 44;
112   R_Sge : constant O_Reg := 45;
113   R_Sle : constant O_Reg := 46;
114   R_Sgt : constant O_Reg := 47;
115
116   subtype Regs_Cc is O_Reg range R_Ov .. R_Sgt;
117
118   R_Edx_Eax : constant O_Reg := 64;
119   R_Ebx_Ecx : constant O_Reg := 65;
120   R_Esi_Edi : constant O_Reg := 66;
121   R_AnyPair : constant O_Reg := 67;
122
123   subtype Regs_Pair is O_Reg range R_Edx_Eax .. R_Esi_Edi;
124
125   R_Any_Xmm : constant O_Reg := 79;
126
127   R_Xmm0  : constant O_Reg := 80;
128   R_Xmm1  : constant O_Reg := R_Xmm0 + 1;
129   R_Xmm2  : constant O_Reg := R_Xmm0 + 2;
130   R_Xmm3  : constant O_Reg := R_Xmm0 + 3;
131   R_Xmm4  : constant O_Reg := R_Xmm0 + 4;
132   R_Xmm5  : constant O_Reg := R_Xmm0 + 5;
133   R_Xmm6  : constant O_Reg := R_Xmm0 + 6;
134   R_Xmm7  : constant O_Reg := R_Xmm0 + 7;
135   R_Xmm8  : constant O_Reg := R_Xmm0 + 8;
136   R_Xmm9  : constant O_Reg := R_Xmm0 + 9;
137   R_Xmm10 : constant O_Reg := R_Xmm0 + 10;
138   R_Xmm11 : constant O_Reg := R_Xmm0 + 11;
139   R_Xmm12 : constant O_Reg := R_Xmm0 + 12;
140   R_Xmm13 : constant O_Reg := R_Xmm0 + 13;
141   R_Xmm14 : constant O_Reg := R_Xmm0 + 14;
142   R_Xmm15 : constant O_Reg := R_Xmm0 + 15;
143
144   subtype Regs_X86_64_Xmm is O_Reg range R_Xmm0 .. R_Xmm15;
145   subtype Regs_X86_Xmm is O_Reg range R_Xmm0 .. R_Xmm7;
146   subtype Regs_Xmm is O_Reg range R_Xmm0 .. R_Xmm15;
147   subtype Regs_Xmm8_Xmm15 is O_Reg range R_Xmm8 .. R_Xmm15;
148
149   function Get_Pair_High (Reg : Regs_Pair) return Regs_R32;
150   function Get_Pair_Low (Reg : Regs_Pair) return Regs_R32;
151
152   function Inverse_Cc (R : O_Reg) return O_Reg;
153
154   --  Intrinsic subprograms.
155   Intrinsic_Mul_Ov_U64 : constant Int32 := 1;
156   Intrinsic_Div_Ov_U64 : constant Int32 := 2;
157   Intrinsic_Mod_Ov_U64 : constant Int32 := 3;
158   Intrinsic_Mul_Ov_I64 : constant Int32 := 4;
159   Intrinsic_Div_Ov_I64 : constant Int32 := 5;
160   Intrinsic_Mod_Ov_I64 : constant Int32 := 6;
161   Intrinsic_Rem_Ov_I64 : constant Int32 := 7;
162
163   subtype Intrinsics_X86 is Int32
164     range Intrinsic_Mul_Ov_U64 .. Intrinsic_Rem_Ov_I64;
165
166   type O_Reg_Array is array (Natural range <>) of O_Reg;
167
168   type O_Reg_Bitmap is array (O_Reg range <>) of Boolean;
169   pragma Pack (O_Reg_Bitmap);
170
171   subtype Regs_R32_Bitmap is O_Reg_Bitmap (Regs_R32);
172   subtype Regs_R64_Bitmap is O_Reg_Bitmap (Regs_R64);
173   subtype Regs_Xmm64_Bitmap is O_Reg_Bitmap (Regs_X86_64_Xmm);
174
175   --  Registers preserved accross calls.
176   Preserved_Regs_32 : constant Regs_R32_Bitmap :=
177     (R_Di | R_Si | R_Bx => True, others => False);
178   Preserved_Regs_Lin64 : constant Regs_R64_Bitmap :=
179     (R_Bx | R_R12 | R_R13 | R_R14 | R_R15 => True, others => False);
180   Preserved_Regs_Win64 : constant Regs_R64_Bitmap :=
181     (R_Di | R_Si | R_Bx | R_R12 | R_R13 | R_R14 | R_R15 => True,
182      others => False);
183   Preserved_Xmm_Win64 : constant Regs_Xmm64_Bitmap :=
184     (R_Xmm6 | R_Xmm7 | R_Xmm8 | R_Xmm9 | R_Xmm1 | R_Xmm11
185        | R_Xmm12 | R_Xmm13 | R_Xmm14 | R_Xmm15 => True,
186      others => False);
187end Ortho_Code.X86;
188