40
41
let is_intconst = function Cconst_int n -> true | _ -> false
43
(* Soft emulation of float comparisons *)
45
let float_comparison_function = function
42
53
(* Instruction selection *)
43
54
class selector = object(self)
45
56
inherit Selectgen.selector_generic as super
58
method! regs_for tyv =
59
(* Expand floats into pairs of integer registers *)
60
let nty = Array.length tyv in
62
if i >= nty then [] else begin
64
| Float -> Int :: Int :: expand (i+1)
65
| ty -> ty :: expand (i+1)
67
Reg.createv (Array.of_list (expand 0))
47
69
method is_immediate n =
48
70
n land 0xFF = n || is_immed n 2
115
137
super#select_operation op args
139
(* Turn floating-point operations into library function calls *)
140
| Caddf -> (Iextcall("__adddf3", false), args)
141
| Csubf -> (Iextcall("__subdf3", false), args)
142
| Cmulf -> (Iextcall("__muldf3", false), args)
143
| Cdivf -> (Iextcall("__divdf3", false), args)
144
| Cfloatofint -> (Iextcall("__floatsidf", false), args)
145
| Cintoffloat -> (Iextcall("__fixdfsi", false), args)
147
(Iintop_imm(Icomp(Isigned comp), 0),
148
[Cop(Cextcall(float_comparison_function comp,
149
typ_int, false, Debuginfo.none),
151
(* Add coercions around loads and stores of 32-bit floats *)
153
(Iextcall("__extendsfdf2", false), [Cop(Cload Word, args)])
155
begin match args with
158
Cop(Cextcall("__truncdfsf2", typ_int, false, Debuginfo.none),
160
self#select_operation (Cstore Word) [arg1; arg2']
163
(* Other operations are regular *)
117
164
| _ -> super#select_operation op args
119
(* In mul rd, rm, rs, the registers rm and rd must be different.
166
method! select_condition = function
167
| Cop(Ccmpf cmp, args) ->
168
(Iinttest_imm(Isigned cmp, 0),
169
Cop(Cextcall(float_comparison_function cmp,
170
typ_int, false, Debuginfo.none),
173
super#select_condition expr
175
(* Deal with some register irregularities:
177
1- In mul rd, rm, rs, the registers rm and rd must be different.
120
178
We deal with this by pretending that rm is also a result of the mul
123
method insert_op_debug op dbg rs rd =
124
if op = Iintop(Imul) then begin
125
self#insert_debug (Iop op) dbg rs [| rd.(0); rs.(0) |]; rd
127
super#insert_op_debug op dbg rs rd
181
2- For Inegf and Iabsf, force arguments and results in (r0, r1);
182
this simplifies code generation later.
185
method! insert_op_debug op dbg rs rd =
188
self#insert_debug (Iop op) dbg rs [| rd.(0); rs.(0) |]; rd
190
let r = [| phys_reg 0; phys_reg 1 |] in
191
self#insert_moves rs r;
192
self#insert_debug (Iop op) dbg r r;
193
self#insert_moves r rd;
196
super#insert_op_debug op dbg rs rd
131
200
let fundecl f = (new selector)#emit_fundecl f