Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / diag / assembly / include / nmacros.h
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: nmacros.h
5* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
6* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
7*
8* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9*
10* This program is free software; you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation; version 2 of the License.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License
20* along with this program; if not, write to the Free Software
21* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*
23* For the avoidance of doubt, and except that if any non-GPL license
24* choice is available it will apply instead, Sun elects to use only
25* the General Public License version 2 (GPLv2) at this time for any
26* software where a choice of GPL license versions is made
27* available with the language indicating that GPLv2 or any later version
28* may be used, or where a choice of which version of the GPL is applied is
29* otherwise unspecified.
30*
31* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
32* CA 95054 USA or visit www.sun.com if you need additional information or
33* have any questions.
34*
35*
36* ========== Copyright Header End ============================================
37*/
38#ifndef __NMACROS_H__
39#define __NMACROS_H__
40/****************** STRCAT(str1, str2, ...., str9) ***************************
41
42 This is a support macro used to concatenate upto 9 strings (arguments)
43
44******************************************************************************/
45
46define(STRCAT, $1$2$3$4$5$6$7$8$9)
47
48/***************************** INIT_DW_REG(val, reg) **************************
49
50 This macro expands incrementally, depending on the size of the 'val' argument,
51 to initialize the integer register 'reg'. No temporary register is required.
52
53******************************************************************************/
54
55define(INIT_DW_REG,
56 `define(`hi_val', substr($1, 0, 10)) dnl
57 define(`lo_val2', STRCAT(0x, substr($1, 10, 2))) dnl
58 define(`lo_val1', STRCAT(0x, substr($1, 12, 3))) dnl
59 define(`lo_val0', STRCAT(0x, substr($1, 15)))
60 set hi_val, $2
61 sllx $2, eval(len(lo_val2)*4-8), $2
62 or $2, lo_val2, $2
63 ifelse(lo_val1,0x,,
64 `sllx $2, eval(len(lo_val1)*4-8), $2
65 or $2, lo_val1, $2')
66 ifelse(lo_val0,0x,,
67 `sllx $2, eval(len(lo_val0)*4-8), $2
68 or $2, lo_val0, $2')')
69
70/************************** INIT_INT_REG(reg, val) ****************************
71
72 This is a general purpose macro to initialize any 64 bit integer register
73 without having to use a temporary register. It uses `INIT_DW_REG' defined
74 above. This macro forms the basis of all initialization/comparison macros
75 defined below.
76
77******************************************************************************/
78
79define(INIT_INT_REG,
80 `ifelse(substr($2,0,1),%,`mov $2, $1',
81 `ifelse(eval(len($2)>10),1,`INIT_DW_REG($2, $1)',` set $2, $1')')')
82
83/*************************** CMP_INT_REG(reg, val) ****************************
84
85 This macro compares 'val' with the contents of the integer register 'reg'. It
86 uses %g4 as scratch register. Only one scratch register is required
87 irrespective of the size of 'val'. Note that the macro can replace ALL
88 existing (integer) result checking macros with potentially fewer instructions
89 for values > 32 bits and uses only ONE scratch register in all cases.
90
91******************************************************************************/
92
93define(CMP_INT_REG,
94 `INIT_INT_REG(%g4, $2)
95 sub $1, %g4, %g4
96 brz,pt %g4, 1f
97 nop
98 ta BAD_TRAP
991:')
100
101
102
103/****************** MEM_STORE(val, dest_addr, offset) *************************
104
105 This is a support macro used by the FP macros defined below. As evident from
106 it's syntax, it stores 'val' at optional offset 'offset' from a base address
107 'dest_addr'. %g4 and %g5 are used as scratch registers.
108
109******************************************************************************/
110
111define(MEM_STORE,
112 `INIT_INT_REG(%g4, $1)
113 set $2, %g5
114 ifelse(eval(len($3)>0),1,`add %g5, $3, %g5')
115 ifelse(eval(len($1)>10),1,`stx %g4, [%g5]',`st %g4, [%g5]')')
116
117
118/************************* INIT_FP_REG(freg, val1, val2) *********************
119
120 This macro initializes the FP register 'freg' with a SP/DP/QP number. 'val2'
121 is optional and should only be supplied for QP numbers. Note that the syntax
122 is similar to the macro `INIT_INT_REG' defined above for initializing an
123 integer register.
124
125 The macro uses %g4 and %g5 as scratch registers and a predefined area in
126 memory labeled 'scratch_area' for temporary storage.
127
128******************************************************************************/
129
130define(INIT_FP_REG,
131 `MEM_STORE($2, scratch_area)
132 ifelse(eval(len($3)>0),1,`MEM_STORE($3, scratch_area, 8)')
133 set scratch_area, %g5
134 ifelse(eval(len($3)>0),1,`ldq [%g5], $1',
135 eval(len($2)>10),1,`ldd [%g5], $1',`ld [%g5], $1')')
136
137
138/****************** INIT_TH_FP_REG(memptr, freg, val) ************************
139
140 This macro initializes the FP register 'freg' with a SP/DP/QP number. 'val2'
141 is optional and should only be supplied for QP numbers. Note that the syntax
142 is similar to the macro `INIT_INT_REG' defined above for initializing an
143 integer register.
144
145 The macro uses %g4 and %g5 as scratch registers and a predefined area in
146 memory pointed by memptr for temporary storage.
147
148******************************************************************************/
149
150define(INIT_TH_FP_REG,
151 `setx $3, %g4, %g5
152 stx %g5, [$1]
153 ldd [$1], $2')
154
155
156
157/************************ COPY_REG(reg, copy_inst) **************************
158
159 This macro copies register 'reg' to/from memory. The caller supplies the
160 the instruction type for the desired data transfer. %g4 is assumed to contain
161 the memory address for the source/destination for the copy operation.
162
163*****************************************************************************/
164
165define(COPY_REG,
166 `ifelse(substr($2, 0, 2),ld,`$2 [%g4], $1',`$2 $1, [%g4]')')
167
168
169/************************* CMP_FP_REG(freg, val1, val2) **********************
170
171 This macro compares a SP/DP/QP number in 'val1, val2' with the contents of
172 the FP register 'freg'. 'val2' is optional and should only be specified for
173 comparing QP values. Note the similarity in synatx with this macro's integer
174 counterpart defined above in `CMP_INT_REG'. Also note that it can replace ALL
175 result checking macros for FP values with potentially fewer instructions for
176 DP and QP numbers.
177
178 The macro uses %g4 and %g5 as scratch registers and a predefined area in
179 memory labeled 'scratch_area' for temporary storage.
180
181
182*****************************************************************************/
183
184define(CMP_FP_REG,
185` set scratch_area, %g4
186 ifelse(eval(len($3)>0),1,`COPY_REG($1, stq)',
187 eval(len($2)>10),1,`COPY_REG($1, std)',`COPY_REG($1, st)')
188 ifelse(eval(len($2)>10),1,`COPY_REG(%g5, ldx)',`COPY_REG(%g5, ld)')
189 INIT_INT_REG(%g4, $2)
190 sub %g4, %g5, %g4
191 brz,pt %g4, 1f
192 nop
193 ta BAD_TRAP
1941:
195 ifelse(eval(len($3)>0),1,
196`set scratch_area+8, %g4
197 COPY_REG(%g5, ldx)
198 INIT_INT_REG(%g4, $3)
199 sub %g4, %g5
200 brz,pt %g4, 2f
201 nop
202 ta BAD_TRAP
2032:')
204 nop')
205
206
207/************************ INIT_REG(any_reg, val1, val2) *************************
208
209 This is a truly generic macro for initializing any integer or FP register
210 without having to use separate macros. 'val2' is optional ans should only
211 be supplied for QP (FP) numbers. The macro calls one of the two initialization
212 macros defined above based on the register 'any_reg'.
213
214 For initializing a FP register, the macro uses %g4 and %g5 as scratch registers
215 and a predefined area in memory called 'scratch_area' for temporary storage.
216
217
218*******************************************************************************/
219define(INIT_REG,
220 `ifelse(eval(len($3)>0),1,`define(`argc', 3)',`define(`argc', 3)')
221 define(`reg_id', substr($1, 0, 2))
222 ifelse(reg_id,%f,`define(`reg_id', FPR)',
223 reg_id,%d,`define(`reg_id', FPR)',
224 reg_id,%q,`define(`reg_id', FPR)',`define(`reg_id', IR)')
225 ifelse(reg_id,FPR,`ifelse(argc,2,`INIT_FP_REG($1, $2)',`INIT_FP_REG($1, $2, $3)')',`INIT_INT_REG($1, $2)')')
226
227
228/************************ CMP_REG(any_reg, val1, val2) *************************
229
230 This is a truly generic macro for comparing any integer or FP register with a
231 value without having to use separate macros. 'val2' is optional and should only
232 be supplied for QP (FP) numbers. The macro calls one of the two comparison
233 macros defined above based on the register 'any_reg'.
234
235 For initializing a FP register, the macro uses %f16, %g4 and %g5 as scratch
236 registers and a predefined area in memory called 'scratch_area' for temporary
237 storage. Only %g4 is used as a scratch register for comparing an integer register.
238
239*******************************************************************************/
240define(CMP_REG,
241 `ifelse(eval(len($3)>0),1,`define(`argc', 3)',`define(`argc', 3)')
242 define(`reg_id', substr($1, 0, 2))
243 ifelse(reg_id,%f,`define(`reg_id', FPR)',
244 reg_id,%d,`define(`reg_id', FPR)',
245 reg_id,%q,`define(`reg_id', FPR)',`define(`reg_id', IR)')
246 ifelse(reg_id,FPR,`ifelse(argc,2,`CMP_FP_REG($1, $2)',`CMP_FP_REG($1, $2, $3)')',`CMP_INT_REG($1, $2)')')
247
248
249define(CLR_GLOBALS,
250 `clr %g1
251 clr %g2
252 clr %g3
253 clr %g4
254 clr %g5
255 clr %g6
256 clr %g7')
257
258define(CLR_LOCALS,
259 `clr %l0
260 clr %l1
261 clr %l2
262 clr %l3
263 clr %l4
264 clr %l5
265 clr %l6
266 clr %l7')
267
268define(CLR_OUTS,
269 `clr %o0
270 clr %o1
271 clr %o2
272 clr %o3
273 clr %o4
274 clr %o5
275 clr %o6
276 clr %o7')
277
278define(CLR_INS,
279 `clr %i0
280 clr %i1
281 clr %i2
282 clr %i3
283 clr %i4
284 clr %i5
285 clr %i6
286 clr %i7')
287
288define(CLR_FPRF,
289 `INIT_REG(%d0, 0x0000000000000000)
290 fmovd %d0, %d2
291 fmovd %d0, %d4
292 fmovd %d0, %d6
293 fmovd %d0, %d8
294 fmovd %d0, %d10
295 fmovd %d0, %d12
296 fmovd %d0, %d14
297 fmovd %d0, %d16
298 fmovd %d0, %d18
299 fmovd %d0, %d20
300 fmovd %d0, %d22
301 fmovd %d0, %d24
302 fmovd %d0, %d26
303 fmovd %d0, %d28
304 fmovd %d0, %d30')
305
306
307define(CLR_DIAG_REGS,
308 `CLR_GLOBALS
309 CLR_LOCALS
310 CLR_OUTS
311 CLR_INS
312 CLR_FPRF')
313
314define(CLR_1WIN1_LOCALS,
315 `rdpr %cwp, %g1
316 inc %g1
317 wrpr %g1, %cwp
318 CLR_LOCALS
319 dec %g1
320 dec %g1
321 wrpr %g1, %cwp
322 CLR_LOCALS
323 inc %g1
324 wrpr %g1, %cwp')
325
326
327
328define(LDST_OP,
329 `ifelse(substr($1, 0, 2),ca,`$1 $2, $3, $4',`ifelse(substr($1, 0, 2),st,`$1 $3, $2',`$1 $2, $3')')')
330
331
332
333define(MAKE_DATA_PA,
334 `INIT_REG(%g4, $1)
335 mov $2, $3
336 sllx $3, 51, $3
337 srlx $3, 51, $3
338 add %g4, $3, $3
339 srlx $3, 3, $3
340 sllx $3, 3, $3
341 mov 1, %g4
342 sllx %g4, 39, %g4
343 or %g4, $3, $3')
344
345define(MAKE_TAG_PA,
346 `INIT_REG(%g4, $1)
347 mov $2, $3
348 sllx $3, 51, $3
349 srlx $3, 51, $3
350 add %g4, $3, $3
351 srlx $3, 6, $3
352 sllx $3, 6, $3
353 mov 2, %g4
354 sllx %g4, 39, %g4
355 or %g4, $3, $3')
356
357
358define(UPSHIFT_INST,
359 `ld [$1], %g4
360 swap [$1-4], %g4
361 st %g4, [$1]
362 sub $1, 4, $1 ! New inst addr
363 srlx $1, 3, %g4
364 sllx %g4, 3, %g4 ! DW flush addr at/before inst after move
365 flush %g4
366 add %g4, 8, %g5 ! Next dW addr
367 flush %g5') ! Needed in case inst was moved to word addr
368
369
370define(ZERO_MEM,
371 `mov $1, %g4 ! Starting MEM addr
372 set $2, %g5 ! ST count
3731:
374 $3 %g0, [%g4] ! Zero fill
375 add %g4, $4, %g4 ! Next addr
376 dec %g5 ! Done?
377 brnz,a %g5, 1b ! No: Continue
378 nop')
379
380
381
382define(NOPS,
383 `define( `NOP_COUNT', eval($1))
384 define( `IT_COUNT', 1)
385 GEN_INSTS')
386
387define(GEN_INSTS,
388 `nop dnl
389 define(`IT_COUNT', incr(IT_COUNT))
390 ifelse(eval(IT_COUNT>NOP_COUNT),1,,`GEN_INSTS')')
391
392
393define(BREAK_GROUP,
394 `mov %y, %g0')
395
396
397#endif