1 |
6 |
jlechner |
; SPARC 32/64 FPU description. -*- Scheme -*-
|
2 |
|
|
; This file contains fpu instructions common to both sparc32/sparc64.
|
3 |
|
|
; It also contains sparc32/64 specific insns, but only when they are a variant
|
4 |
|
|
; of a collection of common ones (at least that's the current theory).
|
5 |
|
|
; Copyright (C) 2000 Red Hat, Inc.
|
6 |
|
|
; This file is part of CGEN.
|
7 |
|
|
; See file COPYING.CGEN for details.
|
8 |
|
|
|
9 |
|
|
; FP support is defined even for cpu's without an fpu as the instructions
|
10 |
|
|
; still have to be assembled and the simulator still has to recognize them
|
11 |
|
|
; so that the appropriate trap can be generated.
|
12 |
|
|
;
|
13 |
|
|
; The physical registers are stored as an array of SI values: here `SI'
|
14 |
|
|
; denotes "set of 32 bits" rather than "32 bit signed integer".
|
15 |
|
|
;
|
16 |
|
|
; wip: currently evaluating the various possibilities
|
17 |
|
|
|
18 |
|
|
; Floating point hardware.
|
19 |
|
|
|
20 |
|
|
; The description needs to know whether the fpu is present.
|
21 |
|
|
; Creating a utility register for this purposes seems reasonable.
|
22 |
|
|
; Might want an attribute to denote it as such.
|
23 |
|
|
|
24 |
|
|
(dsh h-fpu? "h/w fpu present?" () (register BI))
|
25 |
|
|
(dnop fpu? "h/w fpu present?" () h-fpu? f-nil)
|
26 |
|
|
|
27 |
|
|
(define-pmacro (build-freg-name n) ((.sym f n) n))
|
28 |
|
|
|
29 |
|
|
(define-hardware
|
30 |
|
|
(name h-fr32)
|
31 |
|
|
(semantic-name h-fr)
|
32 |
|
|
(comment "sparc32 floating point regs")
|
33 |
|
|
(attrs (MACH32))
|
34 |
|
|
(type register SI (32))
|
35 |
|
|
(indices keyword "%" (.map build-freg-name (.iota 32)))
|
36 |
|
|
)
|
37 |
|
|
(define-hardware
|
38 |
|
|
(name h-fr64)
|
39 |
|
|
(semantic-name h-fr)
|
40 |
|
|
(comment "sparc64 floating point regs")
|
41 |
|
|
(attrs (MACH64))
|
42 |
|
|
(type register SI (64))
|
43 |
|
|
(indices keyword "%" (.map build-freg-name (.iota 64)))
|
44 |
|
|
)
|
45 |
|
|
|
46 |
|
|
(define-hardware
|
47 |
|
|
(name h-frd32)
|
48 |
|
|
(semantic-name h-frd)
|
49 |
|
|
(comment "sparc32 double precision floating point regs")
|
50 |
|
|
(attrs VIRTUAL (MACH32))
|
51 |
|
|
(type register DI (16))
|
52 |
|
|
; ??? This works, but multiple copies of all the register names might be
|
53 |
|
|
; unpalatable. Another way is to specify a register table plus a constraint.
|
54 |
|
|
;(indices keyword "%" (.map build-freg-name (.iota 16 0 2)))
|
55 |
|
|
(get (index) (join DI SI
|
56 |
|
|
(reg h-fr index)
|
57 |
|
|
(reg h-fr (add index 1))))
|
58 |
|
|
(set (index newval)
|
59 |
|
|
(sequence ()
|
60 |
|
|
(set (reg h-fr index) (subword SI newval 0))
|
61 |
|
|
(set (reg h-fr (add index 1)) (subword SI newval 1))))
|
62 |
|
|
)
|
63 |
|
|
|
64 |
|
|
(define-hardware
|
65 |
|
|
(name h-frq32)
|
66 |
|
|
(semantic-name h-frq)
|
67 |
|
|
(comment "sparc32 quad precision floating point regs")
|
68 |
|
|
(attrs VIRTUAL (MACH32))
|
69 |
|
|
(type register TF (8))
|
70 |
|
|
(indices keyword "%" (.map build-freg-name (.iota 8 0 4)))
|
71 |
|
|
(get (index) (join TF SI
|
72 |
|
|
(reg h-fr index)
|
73 |
|
|
(reg h-fr (add index (const 1)))
|
74 |
|
|
(reg h-fr (add index (const 2)))
|
75 |
|
|
(reg h-fr (add index (const 3)))))
|
76 |
|
|
(set (index newval)
|
77 |
|
|
(sequence ()
|
78 |
|
|
(set (reg h-fr index) (subword SI newval 0))
|
79 |
|
|
(set (reg h-fr (add index (const 1))) (subword SI newval 1))
|
80 |
|
|
(set (reg h-fr (add index (const 2))) (subword SI newval 2))
|
81 |
|
|
(set (reg h-fr (add index (const 3))) (subword SI newval 3))))
|
82 |
|
|
)
|
83 |
|
|
|
84 |
|
|
(define-hardware
|
85 |
|
|
(name h-frd64)
|
86 |
|
|
(semantic-name h-frd)
|
87 |
|
|
(comment "sparc64 double precision floating point regs")
|
88 |
|
|
(attrs VIRTUAL (MACH64))
|
89 |
|
|
(type register DF (32))
|
90 |
|
|
(indices keyword "%" (.map build-freg-name (.iota 32 0 2)))
|
91 |
|
|
(get (index) (join DF SI
|
92 |
|
|
(reg h-fr index)
|
93 |
|
|
(reg h-fr (add index (const 1)))))
|
94 |
|
|
(set (index newval)
|
95 |
|
|
(sequence ()
|
96 |
|
|
(set (reg h-fr index) (subword SI newval 0))
|
97 |
|
|
(set (reg h-fr (add index (const 1))) (subword SI newval 1))))
|
98 |
|
|
)
|
99 |
|
|
|
100 |
|
|
(define-hardware
|
101 |
|
|
(name h-frq64)
|
102 |
|
|
(semantic-name h-frq)
|
103 |
|
|
(comment "sparc64 quad precision floating point regs")
|
104 |
|
|
(attrs VIRTUAL (MACH64))
|
105 |
|
|
(type register TF (16))
|
106 |
|
|
(indices keyword "%" (.map build-freg-name (.iota 16 0 4)))
|
107 |
|
|
(get (index) (join TF SI
|
108 |
|
|
(reg h-fr index)
|
109 |
|
|
(reg h-fr (add index (const 1)))
|
110 |
|
|
(reg h-fr (add index (const 2)))
|
111 |
|
|
(reg h-fr (add index (const 3)))))
|
112 |
|
|
(set (index newval)
|
113 |
|
|
(sequence ()
|
114 |
|
|
(set (reg h-fr index) (subword SI newval 0))
|
115 |
|
|
(set (reg h-fr (add index (const 1))) (subword SI newval 1))
|
116 |
|
|
(set (reg h-fr (add index (const 2))) (subword SI newval 2))
|
117 |
|
|
(set (reg h-fr (add index (const 3))) (subword SI newval 3))))
|
118 |
|
|
)
|
119 |
|
|
|
120 |
|
|
; fp condition codes
|
121 |
|
|
|
122 |
|
|
(dsh h-fcc0 "%fcc0" () (register (UINT 2)))
|
123 |
|
|
(dsh h-fcc1 "%fcc1" ((MACH64)) (register (UINT 2)))
|
124 |
|
|
(dsh h-fcc2 "%fcc2" ((MACH64)) (register (UINT 2)))
|
125 |
|
|
(dsh h-fcc3 "%fcc3" ((MACH64)) (register (UINT 2)))
|
126 |
|
|
|
127 |
|
|
; sparc64 fpu control regs
|
128 |
|
|
|
129 |
|
|
(dsh h-fsr-rd "fsr rounding direction" ((MACH64)) (register UQI))
|
130 |
|
|
(dsh h-fsr-tem "fsr trap enable mask" ((MACH64)) (register UQI))
|
131 |
|
|
(dsh h-fsr-ns "fsr nonstandard fp" ((MACH64)) (register BI))
|
132 |
|
|
(dsh h-fsr-ver "fsr version" ((MACH64)) (register UQI))
|
133 |
|
|
(dsh h-fsr-ftt "fsr fp trap type" ((MACH64)) (register UQI))
|
134 |
|
|
(dsh h-fsr-qne "fsr queue not empty" ((MACH64)) (register BI))
|
135 |
|
|
(dsh h-fsr-aexc "fsr accrued exception" ((MACH64)) (register UQI))
|
136 |
|
|
(dsh h-fsr-cexc "fsr current exception" ((MACH64)) (register UQI))
|
137 |
|
|
;(dsh h-fsr "floating point state" ((MACH64)) (register UDI))
|
138 |
|
|
|
139 |
|
|
(dsh h-fpsr-fef "fpsr enable fp" ((MACH64)) (register BI))
|
140 |
|
|
(dsh h-fpsr-du "fpsr dirty upper" ((MACH64)) (register BI))
|
141 |
|
|
(dsh h-fpsr-dl "fpsr dirty lower" ((MACH64)) (register BI))
|
142 |
|
|
|
143 |
|
|
(define-hardware
|
144 |
|
|
(name h-fpsr)
|
145 |
|
|
(comment "fp regs state")
|
146 |
|
|
(attrs VIRTUAL (MACH64))
|
147 |
|
|
(type register UQI)
|
148 |
|
|
(get () (const 0)) ; FIXME
|
149 |
|
|
(set (newval) (set (raw-reg UQI h-fpsr) (const 0))) ; FIXME
|
150 |
|
|
)
|
151 |
|
|
|
152 |
|
|
; Floating point operands.
|
153 |
|
|
|
154 |
|
|
(define-operand
|
155 |
|
|
(name frs1s)
|
156 |
|
|
(comment "single precision floating point source register 1")
|
157 |
|
|
(type h-fr)
|
158 |
|
|
(index f-rs1)
|
159 |
|
|
(mode SF)
|
160 |
|
|
)
|
161 |
|
|
(define-operand
|
162 |
|
|
(name frs2s)
|
163 |
|
|
(comment "single precision floating point source register 2")
|
164 |
|
|
(type h-fr)
|
165 |
|
|
(index f-rs2)
|
166 |
|
|
(mode SF)
|
167 |
|
|
)
|
168 |
|
|
(define-operand
|
169 |
|
|
(name frds)
|
170 |
|
|
(comment "single precision floating point dest'n register")
|
171 |
|
|
(type h-fr)
|
172 |
|
|
(index f-rd)
|
173 |
|
|
(mode SF)
|
174 |
|
|
)
|
175 |
|
|
|
176 |
|
|
(define-operand
|
177 |
|
|
(name frs1d)
|
178 |
|
|
(comment "double precision floating point source register 1")
|
179 |
|
|
(attrs (MACH32))
|
180 |
|
|
(type h-frd)
|
181 |
|
|
(index f-rs1)
|
182 |
|
|
(mode DF)
|
183 |
|
|
)
|
184 |
|
|
(define-operand
|
185 |
|
|
(name frs2d)
|
186 |
|
|
(comment "double precision floating point source register 2")
|
187 |
|
|
(attrs (MACH32))
|
188 |
|
|
(type h-frd)
|
189 |
|
|
(index f-rs2)
|
190 |
|
|
(mode DF)
|
191 |
|
|
)
|
192 |
|
|
(define-operand
|
193 |
|
|
(name frdd)
|
194 |
|
|
(comment "double precision floating point dest'n register")
|
195 |
|
|
(attrs (MACH32))
|
196 |
|
|
(type h-frd)
|
197 |
|
|
(index f-rd)
|
198 |
|
|
(mode DF)
|
199 |
|
|
)
|
200 |
|
|
|
201 |
|
|
(dnop frs1q "quad precision floating point source register 1" ((MACH32))
|
202 |
|
|
h-frq f-rs1)
|
203 |
|
|
(dnop frs2q "quad precision floating point source register 2" ((MACH32))
|
204 |
|
|
h-frq f-rs2)
|
205 |
|
|
(dnop frdq "quad precision floating point dest'n register" ((MACH32))
|
206 |
|
|
h-frq f-rd)
|
207 |
|
|
|
208 |
|
|
; Encoding/decoding of field for sparc64 requires extra effort.
|
209 |
|
|
; See v9 page 40: 5.1.4.1 Floating-Point Register Number Encoding.
|
210 |
|
|
(df f-frs1d-64 "rs1 field for sparc64 DF regs" ((MACH64)) 18 5 UINT
|
211 |
|
|
((value pc) (or INT (srl value (const 5)) (and value (const #x1e))))
|
212 |
|
|
((value pc) (or INT (sll (and value (const 1)) (const 5))
|
213 |
|
|
(and value (const #x1e))))
|
214 |
|
|
)
|
215 |
|
|
(df f-frs2d-64 "rs2 field for sparc64 DF regs" ((MACH64)) 4 5 UINT
|
216 |
|
|
((value pc) (or INT (srl value (const 5)) (and value (const #x1e))))
|
217 |
|
|
((value pc) (or INT (sll (and value (const 1)) (const 5))
|
218 |
|
|
(and value (const #x1e))))
|
219 |
|
|
)
|
220 |
|
|
(df f-frdd-64 "rd field for sparc64 DF regs" ((MACH64)) 29 5 UINT
|
221 |
|
|
((value pc) (or INT (srl value (const 5)) (and value (const #x1e))))
|
222 |
|
|
((value pc) (or INT (sll (and value (const 1)) (const 5))
|
223 |
|
|
(and value (const #x1e))))
|
224 |
|
|
)
|
225 |
|
|
(dnop frs1d "double precision floating point source register 1" ((MACH64))
|
226 |
|
|
h-frd f-frs1d-64)
|
227 |
|
|
(dnop frs2d "double precision floating point source register 2" ((MACH64))
|
228 |
|
|
h-frd f-frs2d-64)
|
229 |
|
|
(dnop frdd "double precision floating point dest'n register" ((MACH64))
|
230 |
|
|
h-frd f-frdd-64)
|
231 |
|
|
|
232 |
|
|
; Encoding/decoding of field for sparc64 requires extra effort.
|
233 |
|
|
; See v9 page 40: 5.1.4.1 Floating-Point Register Number Encoding.
|
234 |
|
|
(df f-frs1q-64 "rs1 field for sparc64 TF regs" ((MACH64)) 18 5 UINT
|
235 |
|
|
((value pc) (or INT (srl value (const 5)) (and value (const #x1e))))
|
236 |
|
|
((value pc) (or INT (sll (and value (const 1)) (const 5))
|
237 |
|
|
(and value (const #x1e))))
|
238 |
|
|
)
|
239 |
|
|
(df f-frs2q-64 "rs2 field for sparc64 TF regs" ((MACH64)) 4 5 UINT
|
240 |
|
|
((value pc) (or INT (srl value (const 5)) (and value (const #x1e))))
|
241 |
|
|
((value pc) (or INT (sll (and value (const 1)) (const 5))
|
242 |
|
|
(and value (const #x1e))))
|
243 |
|
|
)
|
244 |
|
|
(df f-frdq-64 "rd field for sparc64 TF regs" ((MACH64)) 29 5 UINT
|
245 |
|
|
((value pc) (or INT (srl value (const 5)) (and value (const #x1e))))
|
246 |
|
|
((value pc) (or INT (sll (and value (const 1)) (const 5))
|
247 |
|
|
(and value (const #x1e))))
|
248 |
|
|
)
|
249 |
|
|
(dnop frs1q "quad precision floating point source register 1" ((MACH64))
|
250 |
|
|
h-frq f-frs1q-64)
|
251 |
|
|
(dnop frs2q "quad precision floating point source register 2" ((MACH64))
|
252 |
|
|
h-frq f-frs2q-64)
|
253 |
|
|
(dnop frdq "quad precision floating point dest'n register" ((MACH64))
|
254 |
|
|
h-frq f-frdq-64)
|
255 |
|
|
|
256 |
|
|
(dnop fcc0 "%fcc0" () h-fcc0 f-nil)
|
257 |
|
|
|
258 |
|
|
; Misc. support macros.
|
259 |
|
|
; FIXME: TRAP32 wip
|
260 |
|
|
; FIXME: sparc32/sparc64 differences
|
261 |
|
|
; FIXME: trap handling in general (c-call's used until more thought invested)
|
262 |
|
|
|
263 |
|
|
; Check if fpu is present and enabled.
|
264 |
|
|
|
265 |
|
|
(define-pmacro (check-fp-enabled)
|
266 |
|
|
; FIXME: more things to check
|
267 |
|
|
(if (not fpu?)
|
268 |
|
|
(c-call VOID "@cpu@_hw_trap" pc (c-code INT "TRAP32_FP_DIS")))
|
269 |
|
|
)
|
270 |
|
|
|
271 |
|
|
; Return pointer to FPU.
|
272 |
|
|
; ??? wip. maybe move `snan?' to language proper?
|
273 |
|
|
|
274 |
|
|
(define-pmacro (current-fpu) (c-call PTR "CGEN_CPU_FPU"))
|
275 |
|
|
|
276 |
|
|
; Issue appropriate trap if x is an snan.
|
277 |
|
|
|
278 |
|
|
(define-pmacro (check-sf-snan x)
|
279 |
|
|
(if (c-raw-call BI "cgen_sf_snan_p" (current-fpu) x)
|
280 |
|
|
(c-call VOID "@cpu@_hw_trap" pc (c-code INT "TRAP32_FP_DIS"))) ; FIXME
|
281 |
|
|
)
|
282 |
|
|
|
283 |
|
|
(define-pmacro (check-df-snan x)
|
284 |
|
|
(if (c-raw-call BI "cgen_df_snan_p" (current-fpu) x)
|
285 |
|
|
(c-call VOID "@cpu@_hw_trap" pc (c-code INT "TRAP32_FP_DIS"))) ; FIXME
|
286 |
|
|
)
|
287 |
|
|
|
288 |
|
|
; Floating point memory ops.
|
289 |
|
|
|
290 |
|
|
; Note: the startup code uses a load to %f0 to see if an fpu is present.
|
291 |
|
|
; Other startup code tries to set the EF bit in the PSR.
|
292 |
|
|
|
293 |
|
|
(define-pmacro (fp-ld-op name comment op3 mode dest)
|
294 |
|
|
(begin
|
295 |
|
|
(dnmi (.sym name "f-reg") comment ()
|
296 |
|
|
(.str name " [$rs1],$" dest)
|
297 |
|
|
(emit (.sym name f-reg+reg) rs1 (rs2 0) dest))
|
298 |
|
|
(dnmi (.sym name "f-reg+0") comment ()
|
299 |
|
|
(.str name " [$rs1],$" dest)
|
300 |
|
|
(emit (.sym name f-reg+imm) rs1 (simm13 0) dest))
|
301 |
|
|
(dni (.sym name "f-reg+reg") comment ()
|
302 |
|
|
(.str name " [$rs1+$rs2],$" dest)
|
303 |
|
|
(+ OP_3 op3 dest rs1 (f-i 0) (f-res-asi 0) rs2)
|
304 |
|
|
(sequence ()
|
305 |
|
|
(check-fp-enabled)
|
306 |
|
|
(set dest (mem mode (add WI rs1 rs2))))
|
307 |
|
|
())
|
308 |
|
|
(dni (.sym name "f-reg+imm") comment ()
|
309 |
|
|
(.str name " [$rs1+$simm13],$" dest)
|
310 |
|
|
(+ OP_3 op3 dest rs1 (f-i 1) simm13)
|
311 |
|
|
(sequence ()
|
312 |
|
|
(check-fp-enabled)
|
313 |
|
|
(set dest (mem mode (add WI rs1 simm13))))
|
314 |
|
|
())
|
315 |
|
|
(dnmi (.sym name "f-reg/asi") comment ()
|
316 |
|
|
(.str name " [$rs1]$asi,$" dest)
|
317 |
|
|
(emit (.sym name f-reg+reg/asi) rs1 (rs2 0) asi dest))
|
318 |
|
|
(dni (.sym name "f-reg+reg/asi") comment ()
|
319 |
|
|
(.str name " [$rs1+$rs2]$asi,$" dest)
|
320 |
|
|
(+ OP_3 (.sym op3 A) dest rs1 (f-i 0) asi rs2)
|
321 |
|
|
(sequence ()
|
322 |
|
|
(check-fp-enabled)
|
323 |
|
|
(set dest (mem mode (add WI rs1 rs2))))
|
324 |
|
|
())
|
325 |
|
|
)
|
326 |
|
|
)
|
327 |
|
|
(fp-ld-op ld "fp SF load" OP3_LDF SF frds)
|
328 |
|
|
(fp-ld-op ldd "fp DF load" OP3_LDDF DF frdd)
|
329 |
|
|
|
330 |
|
|
(define-pmacro (fp-st-op name comment op3 mode src)
|
331 |
|
|
(begin
|
332 |
|
|
(dnmi (.sym name "f-reg") comment ()
|
333 |
|
|
(.str name " $" src ",[$rs1]")
|
334 |
|
|
(emit (.sym name f-reg+reg) rs1 (rs2 0) src))
|
335 |
|
|
(dnmi (.sym name "f-reg+0") comment ()
|
336 |
|
|
(.str name " $" src ",[$rs1]")
|
337 |
|
|
(emit (.sym name f-reg+imm) rs1 (simm13 0) src))
|
338 |
|
|
(dni (.sym name "f-reg+reg") comment ()
|
339 |
|
|
(.str name " $" src ",[$rs1+$rs2]")
|
340 |
|
|
(+ OP_3 op3 src rs1 (f-i 0) (f-res-asi 0) rs2)
|
341 |
|
|
(sequence ()
|
342 |
|
|
(check-fp-enabled)
|
343 |
|
|
(set (mem mode (add WI rs1 rs2)) src))
|
344 |
|
|
())
|
345 |
|
|
(dni (.sym name "f-reg+imm") comment ()
|
346 |
|
|
(.str name " $" src ",[$rs1+$simm13]")
|
347 |
|
|
(+ OP_3 op3 src rs1 (f-i 1) simm13)
|
348 |
|
|
(sequence ()
|
349 |
|
|
(check-fp-enabled)
|
350 |
|
|
(set (mem mode (add WI rs1 simm13)) src))
|
351 |
|
|
())
|
352 |
|
|
(dnmi (.sym name "f-reg/asi") comment ()
|
353 |
|
|
(.str name " $" src ",[$rs1]$asi")
|
354 |
|
|
(emit (.sym name -reg+reg/asi) rs1 (rs2 0) asi src))
|
355 |
|
|
(dni (.sym name "f-reg+reg/asi") comment ()
|
356 |
|
|
(.str name " $" src ",[$rs1+$rs2]$asi")
|
357 |
|
|
(+ OP_3 (.sym op3 A) src rs1 (f-i 0) asi rs2)
|
358 |
|
|
(sequence ()
|
359 |
|
|
(check-fp-enabled)
|
360 |
|
|
(set (mem mode (add WI rs1 rs2)) src))
|
361 |
|
|
())
|
362 |
|
|
)
|
363 |
|
|
)
|
364 |
|
|
(fp-st-op st "fp SF store" OP3_STF SF frds)
|
365 |
|
|
(fp-st-op std "fp DF store" OP3_STDF DF frdd)
|
366 |
|
|
|
367 |
|
|
; SF mode arithmetic ops.
|
368 |
|
|
|
369 |
|
|
(define-pmacro (sf-unary-op name comment op3 fpop1 fn)
|
370 |
|
|
(begin
|
371 |
|
|
(dni name comment ()
|
372 |
|
|
(.str name " $frs1s,$frds")
|
373 |
|
|
(+ OP_2 op3 fpop1 frds frs1s (f-rs2 0))
|
374 |
|
|
(sequence ()
|
375 |
|
|
(check-fp-enabled)
|
376 |
|
|
(set frds (fn frs1s))
|
377 |
|
|
; ??? dest is modified if snan, assign to tmp first?
|
378 |
|
|
; [grep for all check-*-snan's]
|
379 |
|
|
(check-sf-snan frds))
|
380 |
|
|
())
|
381 |
|
|
)
|
382 |
|
|
)
|
383 |
|
|
|
384 |
|
|
(define-pmacro (sf-binary-op name comment op3 fpop1 fn)
|
385 |
|
|
(begin
|
386 |
|
|
(dni name comment ()
|
387 |
|
|
(.str name " $frs1s,$frs2s,$frds")
|
388 |
|
|
(+ OP_2 op3 fpop1 frds frs1s frs2s)
|
389 |
|
|
(sequence ()
|
390 |
|
|
(check-fp-enabled)
|
391 |
|
|
(set frds (fn frs1s frs2s))
|
392 |
|
|
(check-sf-snan frds))
|
393 |
|
|
())
|
394 |
|
|
)
|
395 |
|
|
)
|
396 |
|
|
|
397 |
|
|
(sf-unary-op fnegs "32 bit fp neg" OP3_FPOPS1 FPOPS1_FNEGS neg)
|
398 |
|
|
(sf-unary-op fabss "32 bit fp abs" OP3_FPOPS1 FPOPS1_FABSS abs)
|
399 |
|
|
|
400 |
|
|
(sf-binary-op fadds "32 bit fp add" OP3_FPOPS1 FPOPS1_FADDS add)
|
401 |
|
|
(sf-binary-op fsubs "32 bit fp sub" OP3_FPOPS1 FPOPS1_FSUBS sub)
|
402 |
|
|
(sf-binary-op fmuls "32 bit fp mul" OP3_FPOPS1 FPOPS1_FMULS mul)
|
403 |
|
|
(sf-binary-op fdivs "32 bit fp div" OP3_FPOPS1 FPOPS1_FDIVS div)
|
404 |
|
|
|
405 |
|
|
; ??? floating point compares are wip
|
406 |
|
|
|
407 |
|
|
(dni fp-fcmps "32 bit compare" ()
|
408 |
|
|
"fcmps $frs1s,$frs2s"
|
409 |
|
|
(+ OP_2 OP3_FPOPS2 FPOPS2_FCMPS (f-rd 0) frs1s frs2s)
|
410 |
|
|
(sequence ()
|
411 |
|
|
(check-fp-enabled)
|
412 |
|
|
(set fcc0 (c-call UINT "SFCMP" frs1s frs2s)))
|
413 |
|
|
()
|
414 |
|
|
)
|
415 |
|
|
|
416 |
|
|
(dni fp-fcmpse "32 bit compare, signal if any nans" ()
|
417 |
|
|
"fcmpse $frs1s,$frs2s"
|
418 |
|
|
(+ OP_2 OP3_FPOPS2 FPOPS2_FCMPSE (f-rd 0) frs1s frs2s)
|
419 |
|
|
(sequence ()
|
420 |
|
|
(check-fp-enabled)
|
421 |
|
|
(check-sf-snan frs1s)
|
422 |
|
|
(check-sf-snan frs2s)
|
423 |
|
|
(set fcc0 (c-call UINT "SFCMP" frs1s frs2s)))
|
424 |
|
|
()
|
425 |
|
|
)
|
426 |
|
|
|
427 |
|
|
; DF mode arithmetic ops.
|
428 |
|
|
|
429 |
|
|
(define-pmacro (df-unary-op name comment op3 fpop1 fn)
|
430 |
|
|
(begin
|
431 |
|
|
(dni name comment ()
|
432 |
|
|
(.str name " $frs1d,$frdd")
|
433 |
|
|
(+ OP_2 op3 fpop1 frdd frs1d (f-rs2 0))
|
434 |
|
|
(sequence ()
|
435 |
|
|
(check-fp-enabled)
|
436 |
|
|
(set frdd (fn frs1d))
|
437 |
|
|
(check-df-snan frdd))
|
438 |
|
|
())
|
439 |
|
|
)
|
440 |
|
|
)
|
441 |
|
|
|
442 |
|
|
(define-pmacro (df-binary-op name comment op3 fpop1 fn)
|
443 |
|
|
(begin
|
444 |
|
|
(dni name comment ()
|
445 |
|
|
(.str name " $frs1d,$frs2d,$frdd")
|
446 |
|
|
(+ OP_2 op3 fpop1 frdd frs1d frs2d)
|
447 |
|
|
(sequence ()
|
448 |
|
|
(check-fp-enabled)
|
449 |
|
|
(set frdd (fn frs1d frs2d))
|
450 |
|
|
(check-df-snan frdd))
|
451 |
|
|
())
|
452 |
|
|
)
|
453 |
|
|
)
|
454 |
|
|
|
455 |
|
|
(df-unary-op fnegd "64 bit fp neg" OP3_FPOPS1 FPOPS1_FNEGD neg)
|
456 |
|
|
(df-unary-op fabsd "64 bit fp abs" OP3_FPOPS1 FPOPS1_FABSD abs)
|
457 |
|
|
|
458 |
|
|
(df-binary-op faddd "64 bit fp add" OP3_FPOPS1 FPOPS1_FADDD add)
|
459 |
|
|
(df-binary-op fsubd "64 bit fp sub" OP3_FPOPS1 FPOPS1_FSUBD sub)
|
460 |
|
|
(df-binary-op fmuld "64 bit fp mul" OP3_FPOPS1 FPOPS1_FMULD mul)
|
461 |
|
|
(df-binary-op fdivd "64 bit fp div" OP3_FPOPS1 FPOPS1_FDIVD div)
|
462 |
|
|
|
463 |
|
|
; ??? floating point compares are wip
|
464 |
|
|
|
465 |
|
|
(dni fp-fcmpd "64 bit compare" ()
|
466 |
|
|
"fcmpd $frs1d,$frs2d"
|
467 |
|
|
(+ OP_2 OP3_FPOPS2 FPOPS2_FCMPD (f-rd 0) frs1d frs2d)
|
468 |
|
|
(sequence ()
|
469 |
|
|
(check-fp-enabled)
|
470 |
|
|
(set fcc0 (c-call UINT "DFCMP" frs1d frs2d)))
|
471 |
|
|
()
|
472 |
|
|
)
|
473 |
|
|
|
474 |
|
|
(dni fp-fcmpde "64 bit compare, signal if any nans" ()
|
475 |
|
|
"fcmpde $frs1d,$frs2d"
|
476 |
|
|
(+ OP_2 OP3_FPOPS2 FPOPS2_FCMPDE (f-rd 0) frs1d frs2d)
|
477 |
|
|
(sequence ()
|
478 |
|
|
(check-fp-enabled)
|
479 |
|
|
(check-df-snan frs1d)
|
480 |
|
|
(check-df-snan frs2d)
|
481 |
|
|
(set fcc0 (c-call UINT "DFCMP" frs1d frs2d)))
|
482 |
|
|
()
|
483 |
|
|
)
|
484 |
|
|
|
485 |
|
|
; Branches
|
486 |
|
|
|
487 |
|
|
; CC is one of fcc0,fcc
|
488 |
|
|
(define-pmacro (ftest-u cc) (eq cc FCC_UN))
|
489 |
|
|
(define-pmacro (ftest-g cc) (eq cc FCC_GT))
|
490 |
|
|
(define-pmacro (ftest-ug cc) (orif (eq cc FCC_UN) (eq cc FCC_GT)))
|
491 |
|
|
(define-pmacro (ftest-l cc) (eq cc FCC_LT))
|
492 |
|
|
(define-pmacro (ftest-ul cc) (orif (eq cc FCC_UN) (eq cc FCC_LT)))
|
493 |
|
|
(define-pmacro (ftest-lg cc) (orif (eq cc FCC_LT) (eq cc FCC_GT)))
|
494 |
|
|
(define-pmacro (ftest-ne cc) (ne cc FCC_EQ))
|
495 |
|
|
(define-pmacro (ftest-e cc) (eq cc FCC_EQ))
|
496 |
|
|
(define-pmacro (ftest-ue cc) (orif (eq cc FCC_UN) (eq cc FCC_EQ)))
|
497 |
|
|
(define-pmacro (ftest-ge cc) (orif (eq cc FCC_GT) (eq cc FCC_EQ)))
|
498 |
|
|
(define-pmacro (ftest-uge cc) (ne cc FCC_LT))
|
499 |
|
|
(define-pmacro (ftest-le cc) (orif (eq cc FCC_LT) (eq cc FCC_EQ)))
|
500 |
|
|
(define-pmacro (ftest-ule cc) (ne cc FCC_GT))
|
501 |
|
|
(define-pmacro (ftest-o cc) (ne cc FCC_UN))
|
502 |
|
|
|
503 |
|
|
(define-pmacro (fbfcc-branch bname comment cond test br-sem)
|
504 |
|
|
(begin
|
505 |
|
|
(dni bname (.str "fp branch " comment) (V9-DEPRECATED)
|
506 |
|
|
(.str bname "$a $disp22")
|
507 |
|
|
(+ OP_0 a cond OP2_FBFCC disp22)
|
508 |
|
|
(br-sem test fcc0)
|
509 |
|
|
())
|
510 |
|
|
)
|
511 |
|
|
)
|
512 |
|
|
(fbfcc-branch fba "always" FCOND_A test-always uncond-br-sem)
|
513 |
|
|
(fbfcc-branch fbn "never" FCOND_N test-never uncond-br-sem)
|
514 |
|
|
(fbfcc-branch fbu "unordered" FCOND_U ftest-u cond-br-sem)
|
515 |
|
|
(fbfcc-branch fbg "greater" FCOND_G ftest-g cond-br-sem)
|
516 |
|
|
(fbfcc-branch fbug "unordered or greater" FCOND_UG ftest-ug cond-br-sem)
|
517 |
|
|
(fbfcc-branch fbl "less" FCOND_L ftest-l cond-br-sem)
|
518 |
|
|
(fbfcc-branch fbul "unordered or less" FCOND_UL ftest-ul cond-br-sem)
|
519 |
|
|
(fbfcc-branch fblg "less or greater" FCOND_LG ftest-lg cond-br-sem)
|
520 |
|
|
(fbfcc-branch fbne "not equal" FCOND_NE ftest-ne cond-br-sem)
|
521 |
|
|
(fbfcc-branch fbe "equal" FCOND_E ftest-e cond-br-sem)
|
522 |
|
|
(fbfcc-branch fbue "unordered or equal" FCOND_UE ftest-ue cond-br-sem)
|
523 |
|
|
(fbfcc-branch fbge "greater or equal" FCOND_GE ftest-ge cond-br-sem)
|
524 |
|
|
(fbfcc-branch fbuge "unordered or greater or equal" FCOND_UGE ftest-uge cond-br-sem)
|
525 |
|
|
(fbfcc-branch fble "less or equal" FCOND_LE ftest-le cond-br-sem)
|
526 |
|
|
(fbfcc-branch fbule "unordered or less or equal" FCOND_ULE ftest-ule cond-br-sem)
|
527 |
|
|
(fbfcc-branch fbo "ordered" FCOND_O ftest-o cond-br-sem)
|