Annotation of tme/ic/sparc/sparc-insns.c, revision 1.1.1.1

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"

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.