|
|
1.1 root 1: /* $Id: sparc-insns.c,v 1.5 2007/03/29 01:07:46 fredette Exp $ */
2:
3: /* ic/sparc/sparc-insns.c - SPARC instruction functions: */
4:
5: /*
6: * Copyright (c) 2005 Matt Fredette
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by Matt Fredette.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33: * POSSIBILITY OF SUCH DAMAGE.
34: */
35:
36: /* includes: */
37: #include "sparc-impl.h"
38:
39: _TME_RCSID("$Id: sparc-insns.c,v 1.5 2007/03/29 01:07:46 fredette Exp $");
40:
41: #include "sparc-bus-auto.c"
42:
43: TME_SPARC_FORMAT3(tme_sparc32_illegal, tme_uint32_t)
44: {
45: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
46: }
47:
48: /* the coprocessor instructions are all illegal for now: */
49: TME_SPARC_FORMAT3(tme_sparc32_cpop1, tme_uint32_t)
50: {
51: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
52: }
53: TME_SPARC_FORMAT3(tme_sparc32_cpop2, tme_uint32_t)
54: {
55: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
56: }
57: TME_SPARC_FORMAT3(tme_sparc32_ldc, tme_uint32_t)
58: {
59: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
60: }
61: TME_SPARC_FORMAT3(tme_sparc32_ldcsr, tme_uint32_t)
62: {
63: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
64: }
65: TME_SPARC_FORMAT3(tme_sparc32_lddc, tme_uint32_t)
66: {
67: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
68: }
69: TME_SPARC_FORMAT3(tme_sparc32_stc, tme_uint32_t)
70: {
71: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
72: }
73: TME_SPARC_FORMAT3(tme_sparc32_stcsr, tme_uint32_t)
74: {
75: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
76: }
77: TME_SPARC_FORMAT3(tme_sparc32_stdc, tme_uint32_t)
78: {
79: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
80: }
81: TME_SPARC_FORMAT3(tme_sparc32_stdcq, tme_uint32_t)
82: {
83: TME_SPARC_INSN_PRIV;
84: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
85: }
86:
87: TME_SPARC_FORMAT3(tme_sparc32_rdasr, tme_uint32_t)
88: {
89: unsigned int reg_rs1;
90: unsigned int reg_rd;
91: tme_uint32_t value;
92:
93: reg_rs1 = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1f << 14));
94: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
95:
96: /* rdy: */
97: if (reg_rs1 == 0) {
98: value = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y);
99: }
100:
101: /* stbar: */
102: else if (reg_rs1 == 15 && reg_rd == 0) {
103: TME_SPARC_INSN_OK;
104: }
105:
106: else {
107:
108: /* all other rdasr instructions are privileged: */
109: TME_SPARC_INSN_PRIV;
110:
111: value = 0;
112: abort();
113: }
114:
115: TME_SPARC_FORMAT3_RD = value;
116: TME_SPARC_INSN_OK;
117: }
118:
119: TME_SPARC_FORMAT3(tme_sparc32_rdpsr, tme_uint32_t)
120: {
121: TME_SPARC_INSN_PRIV;
122: TME_SPARC_FORMAT3_RD = ic->tme_sparc32_ireg_psr;
123:
124: /* the sunos32-type-0 idle type is detected when a "rd %psr, %l0"
125: instruction is followed three instructions later (in disassembly
126: order, not execution order) by a "mov %g1, %psr" that sets PIL
127: to 0xa, and the next write to %psr is a "mov %g1, %psr" that sets
128: PIL to 0x0 and is followed by a branch (to the idle loop): */
129: if (__tme_predict_false((TME_SPARC_INSN
130: & ~((31 << 14) /* rs1 (reserved) */
131: | (1 << 13) /* i (reserved) */
132: | 0x1fff)) /* imm13 (reserved) */
133: == ((tme_uint32_t)
134: (2 << 30) /* format */
135: | (0x10 << 25) /* rd (%l0) */
136: | (0x29 << 19)))) { /* op3 (rdpsr) */
137: /* if we haven't detected the idle loop yet, remember the address
138: of this "rd %psr, %l0" instruction and enter state one: */
139: if (__tme_predict_false(TME_SPARC_IDLE_TYPE_PC_STATE(ic->tme_sparc_idle_type_pc32) != 0)) {
140: if (TME_SPARC_IDLE_TYPE_IS(ic, TME_SPARC_IDLE_TYPE_SUNOS32_TYPE_0)) {
141: ic->tme_sparc_idle_type_pc32
142: = (ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC)
143: + TME_SPARC_IDLE_TYPE_PC_STATE(1));
144: }
145: }
146: }
147:
148: TME_SPARC_INSN_OK;
149: }
150:
151: TME_SPARC_FORMAT3(tme_sparc32_rdwim, tme_uint32_t)
152: {
153: TME_SPARC_INSN_PRIV;
154: TME_SPARC_FORMAT3_RD = ic->tme_sparc32_ireg_wim;
155: TME_SPARC_INSN_OK;
156: }
157:
158: TME_SPARC_FORMAT3(tme_sparc32_rdtbr, tme_uint32_t)
159: {
160: TME_SPARC_INSN_PRIV;
161: TME_SPARC_FORMAT3_RD = ic->tme_sparc32_ireg_tbr;
162: TME_SPARC_INSN_OK;
163: }
164:
165: TME_SPARC_FORMAT3(tme_sparc32_wrasr, tme_uint32_t)
166: {
167: unsigned int reg_rd;
168: tme_uint32_t value_xor;
169:
170: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
171: value_xor = TME_SPARC_FORMAT3_RS1 ^ TME_SPARC_FORMAT3_RS2;
172:
173: /* "WRY ... writes r[rs1] xor r[rs2] if the i field is zero, or
174: r[rs1] xor sign_ext(simm13) if the i field is one, to the
175: writable fields of the specified IU state register. (Note the
176: exclusive-or operation.) Note that WRY is distinguished from
177: WRASR only by the rd field. The rd field must be zero and op3 =
178: 0x30 to write the Y register." */
179: if (reg_rd == 0) {
180: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = value_xor;
181: }
182:
183: else {
184:
185: /* all other wrasr instructions are privileged: */
186: TME_SPARC_INSN_PRIV;
187:
188: abort();
189: }
190:
191: TME_SPARC_INSN_OK;
192: }
193:
194: TME_SPARC_FORMAT3(tme_sparc32_wrpsr, tme_uint32_t)
195: {
196: tme_uint32_t value;
197: tme_uint32_t mask_writable;
198: tme_uint32_t insn;
199: unsigned int cwp;
200:
201: TME_SPARC_INSN_PRIV;
202:
203: /* "WRPSR ... writes r[rs1] xor r[rs2] if the i field is zero, or
204: r[rs1] xor sign_ext(simm13) if the i field is one, to the
205: writable fields of the specified IU state register. (Note the
206: exclusive-or operation.)" */
207: value = TME_SPARC_FORMAT3_RS1 ^ TME_SPARC_FORMAT3_RS2;
208:
209: /* "If the result of a WRPSR instruction would cause the CWP field
210: of the PSR to point to an unimplemented window, it causes an
211: illegal_instruction trap and does not write the PSR." */
212: cwp = TME_FIELD_MASK_EXTRACTU(value, TME_SPARC32_PSR_CWP);
213: if (__tme_predict_false(cwp >= ic->tme_sparc_nwindows)) {
214: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
215: }
216:
217: /* set the new CWP offset: */
218: ic->tme_sparc_cwp_offset = TME_SPARC_CWP_OFFSET(cwp);
219:
220: /* set the new PSR value: */
221: mask_writable = (TME_SPARC32_PSR_ICC
222: | TME_SPARC32_PSR_EC
223: | TME_SPARC32_PSR_EF
224: | TME_SPARC32_PSR_PIL
225: | TME_SPARC32_PSR_S
226: | TME_SPARC32_PSR_PS
227: | TME_SPARC32_PSR_ET
228: | TME_SPARC32_PSR_CWP);
229: value = (value & mask_writable) | (ic->tme_sparc32_ireg_psr & ~mask_writable);
230: ic->tme_sparc32_ireg_psr = value;
231:
232: /* the netbsd32-type-0 idle type is detected when an annulled "wr
233: %g1, PSR_PIL, %psr" or "wr %l1, (IPL_SCHED << 8), %psr"
234: instruction is found four instructions after (in disassembly
235: order, not execution order) a "wr %g1, 0, %psr" or "wr %l1, 0,
236: %psr" instruction that sets PIL to 0x0: */
237: if (__tme_predict_false((TME_SPARC_INSN
238: & ~((31 << 25) /* rd (reserved) */
239: | (0x10 << 14))) /* rs1 (mask %ln to %gn) */
240: == ((tme_uint32_t)
241: (2 << 30) /* format */
242: | (0x31 << 19) /* op3 (wrpsr) */
243: | (0x01 << 14) /* rs1 (%g1) */
244: | (1 << 13) /* i */
245: | 0x0000))) { /* imm13 (0) */
246: if (__tme_predict_false(TME_SPARC_IDLE_TYPE_PC_STATE(ic->tme_sparc_idle_type_pc32) != 0)) {
247: if (TME_SPARC_IDLE_TYPE_IS(ic, TME_SPARC_IDLE_TYPE_NETBSD32_TYPE_0)
248: && ((value & TME_SPARC32_PSR_PIL)
249: == (0x0 * _TME_FIELD_MASK_FACTOR(TME_SPARC32_PSR_PIL)))) {
250: ic->tme_sparc_idle_type_pc32
251: = (ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC)
252: + TME_SPARC_IDLE_TYPE_PC_STATE(1));
253: }
254: }
255: }
256:
257: /* the sunos32-type-0 idle type is detected when a "rd %psr, %l0"
258: instruction is followed three instructions later (in disassembly
259: order, not execution order) by a "mov %g1, %psr" that sets PIL
260: to 0xa, and the next write to %psr is a "mov %g1, %psr" that sets
261: PIL to 0x0 and is followed by a branch (to the idle loop): */
262: if (__tme_predict_false(TME_SPARC_IDLE_TYPE_IS(ic, TME_SPARC_IDLE_TYPE_SUNOS32_TYPE_0))) {
263:
264: /* if we haven't detected the idle loop yet: */
265: if (__tme_predict_false(TME_SPARC_IDLE_TYPE_PC_STATE(ic->tme_sparc_idle_type_pc32) != 0)) {
266:
267: /* if this is a "mov %g1, %psr" instruction: */
268: if (__tme_predict_false((TME_SPARC_INSN
269: & ~((31 << 25) /* rd (reserved) */
270: | 255 << 5)) /* unused (zero) */
271: == ((tme_uint32_t)
272: (2 << 30) /* format */
273: | (0x31 << 19) /* op3 (wrpsr) */
274: | (0x01 << 14) /* rs1 (%g1) */
275: | (0 << 13) /* i */
276: | (0 << 0)))) { /* rs2 (%g0) */
277:
278: /* if this "mov %g1, %psr" instruction is three instructions
279: in disassembly order after a "rd %psr, %l0" instruction and
280: sets PIL to 0xa: */
281: if ((ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC)
282: == (ic->tme_sparc_idle_type_pc32
283: - TME_SPARC_IDLE_TYPE_PC_STATE(1)
284: + (sizeof(tme_uint32_t) * 3)))
285: && ((value & TME_SPARC32_PSR_PIL)
286: == (0xa * _TME_FIELD_MASK_FACTOR(TME_SPARC32_PSR_PIL)))) {
287:
288: /* advance to the next state: */
289: ic->tme_sparc_idle_type_pc32 = TME_SPARC_IDLE_TYPE_PC_STATE(3);
290: }
291:
292: /* otherwise, if we detected a "mov %g1, %psr" instruction
293: three instructions in disassembly order after a "rd %psr,
294: %l0" instruction, and this "mov %g1, %psr" instruction sets
295: PIL to 0x0, and the next instruction is an unconditional
296: branch with an annulled delay slot: */
297: else if (ic->tme_sparc_idle_type_pc32 == TME_SPARC_IDLE_TYPE_PC_STATE(3)
298: && ((value & TME_SPARC32_PSR_PIL)
299: == (0x0 * _TME_FIELD_MASK_FACTOR(TME_SPARC32_PSR_PIL)))
300: && (((insn = tme_sparc_fetch_nearby(ic, 1))
301: & ~((0x3fffff << 0))) /* disp22 */
302: == ((0 << 30) /* format */
303: | (1 << 29) /* a */
304: | (8 << 25) /* cond (Always) */
305: | (2 << 22)))) { /* op2 (bicc) */
306:
307: /* we have detected the address of the idle loop: */
308: ic->tme_sparc_idle_type_pc32
309: = (ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC)
310: + sizeof(tme_uint32_t)
311: + (TME_FIELD_MASK_EXTRACTS(insn, (tme_uint32_t) 0x003fffff) << 2));
312: }
313:
314: /* otherwise, this is some other "mov %g1, %psr" instruction,
315: or we couldn't fetch the next instruction or it isn't the
316: expected branch: */
317: else {
318:
319: /* poison the idle type state: */
320: ic->tme_sparc_idle_type_pc32 = TME_SPARC_IDLE_TYPE_PC_STATE(1);
321: }
322: }
323:
324: /* otherwise, this is some other wrpsr instruction: */
325: else {
326:
327: /* poison the idle type state: */
328: ic->tme_sparc_idle_type_pc32 = TME_SPARC_IDLE_TYPE_PC_STATE(1);
329: }
330: }
331: }
332:
333: /* redispatch, since the executor may have cached information
334: derived from the PSR (for example, default data ASI, ITLB, etc.)
335: that we need to invalidate: */
336: tme_sparc_redispatch(ic);
337: /* NOTREACHED */
338: }
339:
340: TME_SPARC_FORMAT3(tme_sparc32_wrwim, tme_uint32_t)
341: {
342: tme_uint32_t value;
343:
344: TME_SPARC_INSN_PRIV;
345:
346: /* "WRWIM ... writes r[rs1] xor r[rs2] if the i field is zero, or
347: r[rs1] xor sign_ext(simm13) if the i field is one, to the
348: writable fields of the specified IU state register. (Note the
349: exclusive-or operation.)" */
350: value = TME_SPARC_FORMAT3_RS1 ^ TME_SPARC_FORMAT3_RS2;
351:
352: /* "A WRWIM with all bits set to 1, followed by a RDWIM, yields a
353: bit vector in which the imple- mented windows (and only the
354: implemented windows) are indicated by 1s." */
355: value &= (0xffffffff >> (32 - ic->tme_sparc_nwindows));
356:
357: ic->tme_sparc32_ireg_wim = value;
358:
359: TME_SPARC_INSN_OK;
360: }
361:
362: TME_SPARC_FORMAT3(tme_sparc32_wrtbr, tme_uint32_t)
363: {
364: tme_uint32_t value;
365:
366: TME_SPARC_INSN_PRIV;
367:
368: /* "WRTBR ... writes r[rs1] xor r[rs2] if the i field is zero, or
369: r[rs1] xor sign_ext(simm13) if the i field is one, to the
370: writable fields of the specified IU state register. (Note the
371: exclusive-or operation.)" */
372: value = TME_SPARC_FORMAT3_RS1 ^ TME_SPARC_FORMAT3_RS2;
373:
374: /* "Bits 11 through 4 comprise the trap type (tt) field. This 8-bit
375: field is written by the hardware when a trap occurs, and retains
376: its value until the next trap. It provides an offset into the
377: trap table. The WRTBR instruction does not affect the tt
378: field. TBR_zero (0) Bits 3 through 0 are zeroes. The WRTBR
379: instruction does not affect this field. For future compatibility,
380: supervisor software should only issue a WRTBR instruction with a
381: zero value in this field." */
382: value = (value & 0xfffff000) | (ic->tme_sparc32_ireg_tbr & 0x00000ff0);
383: ic->tme_sparc32_ireg_tbr = value;
384:
385: TME_SPARC_INSN_OK;
386: }
387:
388: TME_SPARC_FORMAT3(tme_sparc32_flush, tme_uint32_t)
389: {
390: /* nothing to do */
391: TME_SPARC_INSN_OK;
392: }
393:
394: TME_SPARC_FORMAT3(tme_sparc32_rett, tme_uint32_t)
395: {
396: tme_uint32_t psr;
397: unsigned int cwp;
398: tme_uint32_t pc_next_next;
399:
400: /* "One of several traps may occur when an RETT is executed. These
401: are described in priority order (highest priority first):
402:
403: If traps are enabled (ET=1) and the processor is in user mode
404: (S=0), a privileged_instruction trap occurs.
405:
406: If traps are enabled (ET=1) and the processor is in supervisor
407: mode (S=1), an illegal_instruction trap occurs.
408:
409: If traps are disabled (ET=0), and (a) the processor is in user
410: mode (S=0), or (b) a window_underflow condition is detected (WIM
411: and 2^new_CWP ) = 1, or (c) either of the low-order two bits of
412: the target address is nonzero, then the processor indicates a
413: trap condition of (a) privileged_instruction, (b)
414: window_underflow, or (c) mem_address_not_aligned (respectively)
415: in the tt field of the TBR register, and enters the error_mode
416: state." */
417: psr = ic->tme_sparc32_ireg_psr;
418:
419: if (__tme_predict_false((psr & TME_SPARC32_PSR_S) == 0)) {
420: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_privileged_instruction);
421: }
422:
423: if (__tme_predict_false((psr & TME_SPARC32_PSR_ET) != 0)) {
424: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_illegal_instruction);
425: }
426:
427: cwp = TME_FIELD_MASK_EXTRACTU(psr, TME_SPARC32_PSR_CWP);
428: cwp += 1;
429: cwp %= ic->tme_sparc_nwindows;
430: if (ic->tme_sparc32_ireg_wim & (((tme_uint32_t) 1) << cwp)) {
431: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_window_underflow);
432: }
433:
434: pc_next_next = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
435: if (__tme_predict_false((pc_next_next % sizeof(tme_uint32_t)) != 0)) {
436: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_mem_address_not_aligned);
437: }
438:
439: /* set the new PSR: */
440: TME_FIELD_MASK_DEPOSITU(psr, TME_SPARC32_PSR_CWP, cwp);
441: psr |= TME_SPARC32_PSR_ET;
442: psr &= ~TME_SPARC32_PSR_S;
443: psr |= ((psr & TME_SPARC32_PSR_PS) * (TME_SPARC32_PSR_S / TME_SPARC32_PSR_PS));
444: ic->tme_sparc32_ireg_psr = psr;
445:
446: /* set the new CWP offset: */
447: ic->tme_sparc_cwp_offset = TME_SPARC_CWP_OFFSET(cwp);
448:
449: /* set the delayed control transfer: */
450: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC_NEXT_NEXT) = pc_next_next;
451:
452: /* redispatch, since the executor may have cached information
453: derived from the PSR (for example, default data ASI, ITLB, etc.)
454: that we need to invalidate: */
455: tme_sparc_redispatch(ic);
456: }
457:
458: TME_SPARC_FORMAT3(tme_sparc32_save_restore, tme_uint32_t)
459: {
460: int direction;
461: tme_uint32_t psr;
462: unsigned int cwp;
463: unsigned int cwp_offset;
464: unsigned int reg_rd;
465:
466: /* calculate the window direction: */
467: direction = -1 + (((TME_SPARC_INSN & TME_BIT(19)) != 0) * 2);
468:
469: /* calculate the new CWP: */
470: psr = ic->tme_sparc32_ireg_psr;
471: cwp = TME_FIELD_MASK_EXTRACTU(psr, TME_SPARC32_PSR_CWP);
472: cwp += direction;
473: cwp %= ic->tme_sparc_nwindows;
474:
475: /* if the new window is invalid: */
476: if (__tme_predict_false((ic->tme_sparc32_ireg_wim & (((tme_uint32_t) 1) << cwp)) != 0)) {
477: TME_SPARC_INSN_TRAP((direction < 0)
478: ? TME_SPARC_TRAP_window_overflow
479: : TME_SPARC_TRAP_window_underflow);
480: }
481:
482: /* write the new PSR: */
483: TME_FIELD_MASK_DEPOSITU(psr, TME_SPARC32_PSR_CWP, cwp);
484: ic->tme_sparc32_ireg_psr = psr;
485:
486: /* set the new CWP offset: */
487: cwp_offset = TME_SPARC_CWP_OFFSET(cwp);
488: ic->tme_sparc_cwp_offset = cwp_offset;
489:
490: /* decode rd: */
491: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
492: TME_SPARC_REG_INDEX(ic, reg_rd);
493:
494: /* do the add: */
495: ic->tme_sparc_ireg_uint32(reg_rd) = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
496:
497: TME_SPARC_INSN_OK;
498: }
499:
500: TME_SPARC_FORMAT3(tme_sparc32_ticc, tme_uint32_t)
501: {
502: tme_uint8_t conds_mask_icc;
503: tme_uint16_t conds_mask;
504: unsigned int cond;
505:
506: conds_mask_icc = _tme_sparc_conds_icc[TME_FIELD_MASK_EXTRACTU(ic->tme_sparc32_ireg_psr, TME_SPARC32_PSR_ICC)];
507:
508: /* add the not-conditions to the conditions mask: */
509: conds_mask = conds_mask_icc ^ 0xff;
510: conds_mask = (conds_mask << 8) | conds_mask_icc;
511:
512: /* get the condition field: */
513: cond = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xf << 25));
514:
515: /* if this condition is true: */
516: if (conds_mask & TME_BIT(cond)) {
517: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_trap_instruction((TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2) & 0x7f));
518: }
519:
520: TME_SPARC_INSN_OK;
521: }
522:
523: TME_SPARC_FORMAT3(tme_sparc32_fpop1, tme_uint32_t)
524: {
525: tme_sparc_fpu_fpop1(ic);
526: TME_SPARC_INSN_OK;
527: }
528: TME_SPARC_FORMAT3(tme_sparc32_fpop2, tme_uint32_t)
529: {
530: tme_sparc_fpu_fpop2(ic);
531: TME_SPARC_INSN_OK;
532: }
533:
534: #include "sparc-insns-auto.c"
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.