1*66e63ce3Schristos #include "sim-main.h" 2*66e63ce3Schristos #include "v850_sim.h" 3*66e63ce3Schristos #include "simops.h" 4*66e63ce3Schristos 5*66e63ce3Schristos #include <sys/types.h> 6*66e63ce3Schristos 7*66e63ce3Schristos #ifdef HAVE_UTIME_H 8*66e63ce3Schristos #include <utime.h> 9*66e63ce3Schristos #endif 10*66e63ce3Schristos 11*66e63ce3Schristos #ifdef HAVE_TIME_H 12*66e63ce3Schristos #include <time.h> 13*66e63ce3Schristos #endif 14*66e63ce3Schristos 15*66e63ce3Schristos #ifdef HAVE_UNISTD_H 16*66e63ce3Schristos #include <unistd.h> 17*66e63ce3Schristos #endif 18*66e63ce3Schristos 19*66e63ce3Schristos #ifdef HAVE_STRING_H 20*66e63ce3Schristos #include <string.h> 21*66e63ce3Schristos #else 22*66e63ce3Schristos #ifdef HAVE_STRINGS_H 23*66e63ce3Schristos #include <strings.h> 24*66e63ce3Schristos #endif 25*66e63ce3Schristos #endif 26*66e63ce3Schristos 27*66e63ce3Schristos #include "targ-vals.h" 28*66e63ce3Schristos 29*66e63ce3Schristos #include "libiberty.h" 30*66e63ce3Schristos 31*66e63ce3Schristos #include <errno.h> 32*66e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32) 33*66e63ce3Schristos #include <sys/stat.h> 34*66e63ce3Schristos #include <sys/times.h> 35*66e63ce3Schristos #include <sys/time.h> 36*66e63ce3Schristos #endif 37*66e63ce3Schristos 38*66e63ce3Schristos /* This is an array of the bit positions of registers r20 .. r31 in 39*66e63ce3Schristos that order in a prepare/dispose instruction. */ 40*66e63ce3Schristos int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 }; 41*66e63ce3Schristos /* This is an array of the bit positions of registers r16 .. r31 in 42*66e63ce3Schristos that order in a push/pop instruction. */ 43*66e63ce3Schristos int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21}; 44*66e63ce3Schristos /* This is an array of the bit positions of registers r1 .. r15 in 45*66e63ce3Schristos that order in a push/pop instruction. */ 46*66e63ce3Schristos int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21}; 47*66e63ce3Schristos 48*66e63ce3Schristos #ifdef DEBUG 49*66e63ce3Schristos #ifndef SIZE_INSTRUCTION 50*66e63ce3Schristos #define SIZE_INSTRUCTION 18 51*66e63ce3Schristos #endif 52*66e63ce3Schristos 53*66e63ce3Schristos #ifndef SIZE_VALUES 54*66e63ce3Schristos #define SIZE_VALUES 11 55*66e63ce3Schristos #endif 56*66e63ce3Schristos 57*66e63ce3Schristos 58*66e63ce3Schristos unsigned32 trace_values[3]; 59*66e63ce3Schristos int trace_num_values; 60*66e63ce3Schristos unsigned32 trace_pc; 61*66e63ce3Schristos const char *trace_name; 62*66e63ce3Schristos int trace_module; 63*66e63ce3Schristos 64*66e63ce3Schristos 65*66e63ce3Schristos void 66*66e63ce3Schristos trace_input (name, type, size) 67*66e63ce3Schristos char *name; 68*66e63ce3Schristos enum op_types type; 69*66e63ce3Schristos int size; 70*66e63ce3Schristos { 71*66e63ce3Schristos 72*66e63ce3Schristos if (!TRACE_ALU_P (STATE_CPU (simulator, 0))) 73*66e63ce3Schristos return; 74*66e63ce3Schristos 75*66e63ce3Schristos trace_pc = PC; 76*66e63ce3Schristos trace_name = name; 77*66e63ce3Schristos trace_module = TRACE_ALU_IDX; 78*66e63ce3Schristos 79*66e63ce3Schristos switch (type) 80*66e63ce3Schristos { 81*66e63ce3Schristos default: 82*66e63ce3Schristos case OP_UNKNOWN: 83*66e63ce3Schristos case OP_NONE: 84*66e63ce3Schristos case OP_TRAP: 85*66e63ce3Schristos trace_num_values = 0; 86*66e63ce3Schristos break; 87*66e63ce3Schristos 88*66e63ce3Schristos case OP_REG: 89*66e63ce3Schristos case OP_REG_REG_MOVE: 90*66e63ce3Schristos trace_values[0] = State.regs[OP[0]]; 91*66e63ce3Schristos trace_num_values = 1; 92*66e63ce3Schristos break; 93*66e63ce3Schristos 94*66e63ce3Schristos case OP_BIT_CHANGE: 95*66e63ce3Schristos case OP_REG_REG: 96*66e63ce3Schristos case OP_REG_REG_CMP: 97*66e63ce3Schristos trace_values[0] = State.regs[OP[1]]; 98*66e63ce3Schristos trace_values[1] = State.regs[OP[0]]; 99*66e63ce3Schristos trace_num_values = 2; 100*66e63ce3Schristos break; 101*66e63ce3Schristos 102*66e63ce3Schristos case OP_IMM_REG: 103*66e63ce3Schristos case OP_IMM_REG_CMP: 104*66e63ce3Schristos trace_values[0] = SEXT5 (OP[0]); 105*66e63ce3Schristos trace_values[1] = OP[1]; 106*66e63ce3Schristos trace_num_values = 2; 107*66e63ce3Schristos break; 108*66e63ce3Schristos 109*66e63ce3Schristos case OP_IMM_REG_MOVE: 110*66e63ce3Schristos trace_values[0] = SEXT5 (OP[0]); 111*66e63ce3Schristos trace_num_values = 1; 112*66e63ce3Schristos break; 113*66e63ce3Schristos 114*66e63ce3Schristos case OP_COND_BR: 115*66e63ce3Schristos trace_values[0] = State.pc; 116*66e63ce3Schristos trace_values[1] = SEXT9 (OP[0]); 117*66e63ce3Schristos trace_values[2] = PSW; 118*66e63ce3Schristos trace_num_values = 3; 119*66e63ce3Schristos break; 120*66e63ce3Schristos 121*66e63ce3Schristos case OP_LOAD16: 122*66e63ce3Schristos trace_values[0] = OP[1] * size; 123*66e63ce3Schristos trace_values[1] = State.regs[30]; 124*66e63ce3Schristos trace_num_values = 2; 125*66e63ce3Schristos break; 126*66e63ce3Schristos 127*66e63ce3Schristos case OP_STORE16: 128*66e63ce3Schristos trace_values[0] = State.regs[OP[0]]; 129*66e63ce3Schristos trace_values[1] = OP[1] * size; 130*66e63ce3Schristos trace_values[2] = State.regs[30]; 131*66e63ce3Schristos trace_num_values = 3; 132*66e63ce3Schristos break; 133*66e63ce3Schristos 134*66e63ce3Schristos case OP_LOAD32: 135*66e63ce3Schristos trace_values[0] = EXTEND16 (OP[2]); 136*66e63ce3Schristos trace_values[1] = State.regs[OP[0]]; 137*66e63ce3Schristos trace_num_values = 2; 138*66e63ce3Schristos break; 139*66e63ce3Schristos 140*66e63ce3Schristos case OP_STORE32: 141*66e63ce3Schristos trace_values[0] = State.regs[OP[1]]; 142*66e63ce3Schristos trace_values[1] = EXTEND16 (OP[2]); 143*66e63ce3Schristos trace_values[2] = State.regs[OP[0]]; 144*66e63ce3Schristos trace_num_values = 3; 145*66e63ce3Schristos break; 146*66e63ce3Schristos 147*66e63ce3Schristos case OP_JUMP: 148*66e63ce3Schristos trace_values[0] = SEXT22 (OP[0]); 149*66e63ce3Schristos trace_values[1] = State.pc; 150*66e63ce3Schristos trace_num_values = 2; 151*66e63ce3Schristos break; 152*66e63ce3Schristos 153*66e63ce3Schristos case OP_IMM_REG_REG: 154*66e63ce3Schristos trace_values[0] = EXTEND16 (OP[0]) << size; 155*66e63ce3Schristos trace_values[1] = State.regs[OP[1]]; 156*66e63ce3Schristos trace_num_values = 2; 157*66e63ce3Schristos break; 158*66e63ce3Schristos 159*66e63ce3Schristos case OP_IMM16_REG_REG: 160*66e63ce3Schristos trace_values[0] = EXTEND16 (OP[2]) << size; 161*66e63ce3Schristos trace_values[1] = State.regs[OP[1]]; 162*66e63ce3Schristos trace_num_values = 2; 163*66e63ce3Schristos break; 164*66e63ce3Schristos 165*66e63ce3Schristos case OP_UIMM_REG_REG: 166*66e63ce3Schristos trace_values[0] = (OP[0] & 0xffff) << size; 167*66e63ce3Schristos trace_values[1] = State.regs[OP[1]]; 168*66e63ce3Schristos trace_num_values = 2; 169*66e63ce3Schristos break; 170*66e63ce3Schristos 171*66e63ce3Schristos case OP_UIMM16_REG_REG: 172*66e63ce3Schristos trace_values[0] = (OP[2]) << size; 173*66e63ce3Schristos trace_values[1] = State.regs[OP[1]]; 174*66e63ce3Schristos trace_num_values = 2; 175*66e63ce3Schristos break; 176*66e63ce3Schristos 177*66e63ce3Schristos case OP_BIT: 178*66e63ce3Schristos trace_num_values = 0; 179*66e63ce3Schristos break; 180*66e63ce3Schristos 181*66e63ce3Schristos case OP_EX1: 182*66e63ce3Schristos trace_values[0] = PSW; 183*66e63ce3Schristos trace_num_values = 1; 184*66e63ce3Schristos break; 185*66e63ce3Schristos 186*66e63ce3Schristos case OP_EX2: 187*66e63ce3Schristos trace_num_values = 0; 188*66e63ce3Schristos break; 189*66e63ce3Schristos 190*66e63ce3Schristos case OP_LDSR: 191*66e63ce3Schristos trace_values[0] = State.regs[OP[0]]; 192*66e63ce3Schristos trace_num_values = 1; 193*66e63ce3Schristos break; 194*66e63ce3Schristos 195*66e63ce3Schristos case OP_STSR: 196*66e63ce3Schristos trace_values[0] = State.sregs[OP[1]]; 197*66e63ce3Schristos trace_num_values = 1; 198*66e63ce3Schristos } 199*66e63ce3Schristos 200*66e63ce3Schristos } 201*66e63ce3Schristos 202*66e63ce3Schristos void 203*66e63ce3Schristos trace_result (int has_result, unsigned32 result) 204*66e63ce3Schristos { 205*66e63ce3Schristos char buf[1000]; 206*66e63ce3Schristos char *chp; 207*66e63ce3Schristos 208*66e63ce3Schristos buf[0] = '\0'; 209*66e63ce3Schristos chp = buf; 210*66e63ce3Schristos 211*66e63ce3Schristos /* write out the values saved during the trace_input call */ 212*66e63ce3Schristos { 213*66e63ce3Schristos int i; 214*66e63ce3Schristos for (i = 0; i < trace_num_values; i++) 215*66e63ce3Schristos { 216*66e63ce3Schristos sprintf (chp, "%*s0x%.8lx", SIZE_VALUES - 10, "", 217*66e63ce3Schristos (long) trace_values[i]); 218*66e63ce3Schristos chp = strchr (chp, '\0'); 219*66e63ce3Schristos } 220*66e63ce3Schristos while (i++ < 3) 221*66e63ce3Schristos { 222*66e63ce3Schristos sprintf (chp, "%*s", SIZE_VALUES, ""); 223*66e63ce3Schristos chp = strchr (chp, '\0'); 224*66e63ce3Schristos } 225*66e63ce3Schristos } 226*66e63ce3Schristos 227*66e63ce3Schristos /* append any result to the end of the buffer */ 228*66e63ce3Schristos if (has_result) 229*66e63ce3Schristos sprintf (chp, " :: 0x%.8lx", (unsigned long)result); 230*66e63ce3Schristos 231*66e63ce3Schristos trace_generic (simulator, STATE_CPU (simulator, 0), trace_module, buf); 232*66e63ce3Schristos } 233*66e63ce3Schristos 234*66e63ce3Schristos void 235*66e63ce3Schristos trace_output (result) 236*66e63ce3Schristos enum op_types result; 237*66e63ce3Schristos { 238*66e63ce3Schristos if (!TRACE_ALU_P (STATE_CPU (simulator, 0))) 239*66e63ce3Schristos return; 240*66e63ce3Schristos 241*66e63ce3Schristos switch (result) 242*66e63ce3Schristos { 243*66e63ce3Schristos default: 244*66e63ce3Schristos case OP_UNKNOWN: 245*66e63ce3Schristos case OP_NONE: 246*66e63ce3Schristos case OP_TRAP: 247*66e63ce3Schristos case OP_REG: 248*66e63ce3Schristos case OP_REG_REG_CMP: 249*66e63ce3Schristos case OP_IMM_REG_CMP: 250*66e63ce3Schristos case OP_COND_BR: 251*66e63ce3Schristos case OP_STORE16: 252*66e63ce3Schristos case OP_STORE32: 253*66e63ce3Schristos case OP_BIT: 254*66e63ce3Schristos case OP_EX2: 255*66e63ce3Schristos trace_result (0, 0); 256*66e63ce3Schristos break; 257*66e63ce3Schristos 258*66e63ce3Schristos case OP_LOAD16: 259*66e63ce3Schristos case OP_STSR: 260*66e63ce3Schristos trace_result (1, State.regs[OP[0]]); 261*66e63ce3Schristos break; 262*66e63ce3Schristos 263*66e63ce3Schristos case OP_REG_REG: 264*66e63ce3Schristos case OP_REG_REG_MOVE: 265*66e63ce3Schristos case OP_IMM_REG: 266*66e63ce3Schristos case OP_IMM_REG_MOVE: 267*66e63ce3Schristos case OP_LOAD32: 268*66e63ce3Schristos case OP_EX1: 269*66e63ce3Schristos trace_result (1, State.regs[OP[1]]); 270*66e63ce3Schristos break; 271*66e63ce3Schristos 272*66e63ce3Schristos case OP_IMM_REG_REG: 273*66e63ce3Schristos case OP_UIMM_REG_REG: 274*66e63ce3Schristos case OP_IMM16_REG_REG: 275*66e63ce3Schristos case OP_UIMM16_REG_REG: 276*66e63ce3Schristos trace_result (1, State.regs[OP[1]]); 277*66e63ce3Schristos break; 278*66e63ce3Schristos 279*66e63ce3Schristos case OP_JUMP: 280*66e63ce3Schristos if (OP[1] != 0) 281*66e63ce3Schristos trace_result (1, State.regs[OP[1]]); 282*66e63ce3Schristos else 283*66e63ce3Schristos trace_result (0, 0); 284*66e63ce3Schristos break; 285*66e63ce3Schristos 286*66e63ce3Schristos case OP_LDSR: 287*66e63ce3Schristos trace_result (1, State.sregs[OP[1]]); 288*66e63ce3Schristos break; 289*66e63ce3Schristos } 290*66e63ce3Schristos } 291*66e63ce3Schristos #endif 292*66e63ce3Schristos 293*66e63ce3Schristos 294*66e63ce3Schristos /* Returns 1 if the specific condition is met, returns 0 otherwise. */ 295*66e63ce3Schristos int 296*66e63ce3Schristos condition_met (unsigned code) 297*66e63ce3Schristos { 298*66e63ce3Schristos unsigned int psw = PSW; 299*66e63ce3Schristos 300*66e63ce3Schristos switch (code & 0xf) 301*66e63ce3Schristos { 302*66e63ce3Schristos case 0x0: return ((psw & PSW_OV) != 0); 303*66e63ce3Schristos case 0x1: return ((psw & PSW_CY) != 0); 304*66e63ce3Schristos case 0x2: return ((psw & PSW_Z) != 0); 305*66e63ce3Schristos case 0x3: return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0); 306*66e63ce3Schristos case 0x4: return ((psw & PSW_S) != 0); 307*66e63ce3Schristos /*case 0x5: return 1;*/ 308*66e63ce3Schristos case 0x6: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0); 309*66e63ce3Schristos case 0x7: return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) != 0); 310*66e63ce3Schristos case 0x8: return ((psw & PSW_OV) == 0); 311*66e63ce3Schristos case 0x9: return ((psw & PSW_CY) == 0); 312*66e63ce3Schristos case 0xa: return ((psw & PSW_Z) == 0); 313*66e63ce3Schristos case 0xb: return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0); 314*66e63ce3Schristos case 0xc: return ((psw & PSW_S) == 0); 315*66e63ce3Schristos case 0xd: return ((psw & PSW_SAT) != 0); 316*66e63ce3Schristos case 0xe: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0); 317*66e63ce3Schristos case 0xf: return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) == 0); 318*66e63ce3Schristos } 319*66e63ce3Schristos 320*66e63ce3Schristos return 1; 321*66e63ce3Schristos } 322*66e63ce3Schristos 323*66e63ce3Schristos static unsigned long 324*66e63ce3Schristos Add32 (unsigned long a1, unsigned long a2, int * carry) 325*66e63ce3Schristos { 326*66e63ce3Schristos unsigned long result = (a1 + a2); 327*66e63ce3Schristos 328*66e63ce3Schristos * carry = (result < a1); 329*66e63ce3Schristos 330*66e63ce3Schristos return result; 331*66e63ce3Schristos } 332*66e63ce3Schristos 333*66e63ce3Schristos static void 334*66e63ce3Schristos Multiply64 (int sign, unsigned long op0) 335*66e63ce3Schristos { 336*66e63ce3Schristos unsigned long op1; 337*66e63ce3Schristos unsigned long lo; 338*66e63ce3Schristos unsigned long mid1; 339*66e63ce3Schristos unsigned long mid2; 340*66e63ce3Schristos unsigned long hi; 341*66e63ce3Schristos unsigned long RdLo; 342*66e63ce3Schristos unsigned long RdHi; 343*66e63ce3Schristos int carry; 344*66e63ce3Schristos 345*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 346*66e63ce3Schristos 347*66e63ce3Schristos if (sign) 348*66e63ce3Schristos { 349*66e63ce3Schristos /* Compute sign of result and adjust operands if necessary. */ 350*66e63ce3Schristos 351*66e63ce3Schristos sign = (op0 ^ op1) & 0x80000000; 352*66e63ce3Schristos 353*66e63ce3Schristos if (((signed long) op0) < 0) 354*66e63ce3Schristos op0 = - op0; 355*66e63ce3Schristos 356*66e63ce3Schristos if (((signed long) op1) < 0) 357*66e63ce3Schristos op1 = - op1; 358*66e63ce3Schristos } 359*66e63ce3Schristos 360*66e63ce3Schristos /* We can split the 32x32 into four 16x16 operations. This ensures 361*66e63ce3Schristos that we do not lose precision on 32bit only hosts: */ 362*66e63ce3Schristos lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF)); 363*66e63ce3Schristos mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); 364*66e63ce3Schristos mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF)); 365*66e63ce3Schristos hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); 366*66e63ce3Schristos 367*66e63ce3Schristos /* We now need to add all of these results together, taking care 368*66e63ce3Schristos to propogate the carries from the additions: */ 369*66e63ce3Schristos RdLo = Add32 (lo, (mid1 << 16), & carry); 370*66e63ce3Schristos RdHi = carry; 371*66e63ce3Schristos RdLo = Add32 (RdLo, (mid2 << 16), & carry); 372*66e63ce3Schristos RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); 373*66e63ce3Schristos 374*66e63ce3Schristos if (sign) 375*66e63ce3Schristos { 376*66e63ce3Schristos /* Negate result if necessary. */ 377*66e63ce3Schristos 378*66e63ce3Schristos RdLo = ~ RdLo; 379*66e63ce3Schristos RdHi = ~ RdHi; 380*66e63ce3Schristos if (RdLo == 0xFFFFFFFF) 381*66e63ce3Schristos { 382*66e63ce3Schristos RdLo = 0; 383*66e63ce3Schristos RdHi += 1; 384*66e63ce3Schristos } 385*66e63ce3Schristos else 386*66e63ce3Schristos RdLo += 1; 387*66e63ce3Schristos } 388*66e63ce3Schristos 389*66e63ce3Schristos /* Don't store into register 0. */ 390*66e63ce3Schristos if (OP[1]) 391*66e63ce3Schristos State.regs[ OP[1] ] = RdLo; 392*66e63ce3Schristos if (OP[2] >> 11) 393*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = RdHi; 394*66e63ce3Schristos 395*66e63ce3Schristos return; 396*66e63ce3Schristos } 397*66e63ce3Schristos 398*66e63ce3Schristos 399*66e63ce3Schristos /* Read a null terminated string from memory, return in a buffer */ 400*66e63ce3Schristos static char * 401*66e63ce3Schristos fetch_str (sd, addr) 402*66e63ce3Schristos SIM_DESC sd; 403*66e63ce3Schristos address_word addr; 404*66e63ce3Schristos { 405*66e63ce3Schristos char *buf; 406*66e63ce3Schristos int nr = 0; 407*66e63ce3Schristos while (sim_core_read_1 (STATE_CPU (sd, 0), 408*66e63ce3Schristos PC, read_map, addr + nr) != 0) 409*66e63ce3Schristos nr++; 410*66e63ce3Schristos buf = NZALLOC (char, nr + 1); 411*66e63ce3Schristos sim_read (simulator, addr, buf, nr); 412*66e63ce3Schristos return buf; 413*66e63ce3Schristos } 414*66e63ce3Schristos 415*66e63ce3Schristos /* Read a null terminated argument vector from memory, return in a 416*66e63ce3Schristos buffer */ 417*66e63ce3Schristos static char ** 418*66e63ce3Schristos fetch_argv (sd, addr) 419*66e63ce3Schristos SIM_DESC sd; 420*66e63ce3Schristos address_word addr; 421*66e63ce3Schristos { 422*66e63ce3Schristos int max_nr = 64; 423*66e63ce3Schristos int nr = 0; 424*66e63ce3Schristos char **buf = xmalloc (max_nr * sizeof (char*)); 425*66e63ce3Schristos while (1) 426*66e63ce3Schristos { 427*66e63ce3Schristos unsigned32 a = sim_core_read_4 (STATE_CPU (sd, 0), 428*66e63ce3Schristos PC, read_map, addr + nr * 4); 429*66e63ce3Schristos if (a == 0) break; 430*66e63ce3Schristos buf[nr] = fetch_str (sd, a); 431*66e63ce3Schristos nr ++; 432*66e63ce3Schristos if (nr == max_nr - 1) 433*66e63ce3Schristos { 434*66e63ce3Schristos max_nr += 50; 435*66e63ce3Schristos buf = xrealloc (buf, max_nr * sizeof (char*)); 436*66e63ce3Schristos } 437*66e63ce3Schristos } 438*66e63ce3Schristos buf[nr] = 0; 439*66e63ce3Schristos return buf; 440*66e63ce3Schristos } 441*66e63ce3Schristos 442*66e63ce3Schristos 443*66e63ce3Schristos /* sst.b */ 444*66e63ce3Schristos int 445*66e63ce3Schristos OP_380 () 446*66e63ce3Schristos { 447*66e63ce3Schristos trace_input ("sst.b", OP_STORE16, 1); 448*66e63ce3Schristos 449*66e63ce3Schristos store_mem (State.regs[30] + (OP[3] & 0x7f), 1, State.regs[ OP[1] ]); 450*66e63ce3Schristos 451*66e63ce3Schristos trace_output (OP_STORE16); 452*66e63ce3Schristos 453*66e63ce3Schristos return 2; 454*66e63ce3Schristos } 455*66e63ce3Schristos 456*66e63ce3Schristos /* sst.h */ 457*66e63ce3Schristos int 458*66e63ce3Schristos OP_480 () 459*66e63ce3Schristos { 460*66e63ce3Schristos trace_input ("sst.h", OP_STORE16, 2); 461*66e63ce3Schristos 462*66e63ce3Schristos store_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2, State.regs[ OP[1] ]); 463*66e63ce3Schristos 464*66e63ce3Schristos trace_output (OP_STORE16); 465*66e63ce3Schristos 466*66e63ce3Schristos return 2; 467*66e63ce3Schristos } 468*66e63ce3Schristos 469*66e63ce3Schristos /* sst.w */ 470*66e63ce3Schristos int 471*66e63ce3Schristos OP_501 () 472*66e63ce3Schristos { 473*66e63ce3Schristos trace_input ("sst.w", OP_STORE16, 4); 474*66e63ce3Schristos 475*66e63ce3Schristos store_mem (State.regs[30] + ((OP[3] & 0x7e) << 1), 4, State.regs[ OP[1] ]); 476*66e63ce3Schristos 477*66e63ce3Schristos trace_output (OP_STORE16); 478*66e63ce3Schristos 479*66e63ce3Schristos return 2; 480*66e63ce3Schristos } 481*66e63ce3Schristos 482*66e63ce3Schristos /* ld.b */ 483*66e63ce3Schristos int 484*66e63ce3Schristos OP_700 () 485*66e63ce3Schristos { 486*66e63ce3Schristos int adr; 487*66e63ce3Schristos 488*66e63ce3Schristos trace_input ("ld.b", OP_LOAD32, 1); 489*66e63ce3Schristos 490*66e63ce3Schristos adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]); 491*66e63ce3Schristos 492*66e63ce3Schristos State.regs[ OP[1] ] = EXTEND8 (load_mem (adr, 1)); 493*66e63ce3Schristos 494*66e63ce3Schristos trace_output (OP_LOAD32); 495*66e63ce3Schristos 496*66e63ce3Schristos return 4; 497*66e63ce3Schristos } 498*66e63ce3Schristos 499*66e63ce3Schristos /* ld.h */ 500*66e63ce3Schristos int 501*66e63ce3Schristos OP_720 () 502*66e63ce3Schristos { 503*66e63ce3Schristos int adr; 504*66e63ce3Schristos 505*66e63ce3Schristos trace_input ("ld.h", OP_LOAD32, 2); 506*66e63ce3Schristos 507*66e63ce3Schristos adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]); 508*66e63ce3Schristos adr &= ~0x1; 509*66e63ce3Schristos 510*66e63ce3Schristos State.regs[ OP[1] ] = EXTEND16 (load_mem (adr, 2)); 511*66e63ce3Schristos 512*66e63ce3Schristos trace_output (OP_LOAD32); 513*66e63ce3Schristos 514*66e63ce3Schristos return 4; 515*66e63ce3Schristos } 516*66e63ce3Schristos 517*66e63ce3Schristos /* ld.w */ 518*66e63ce3Schristos int 519*66e63ce3Schristos OP_10720 () 520*66e63ce3Schristos { 521*66e63ce3Schristos int adr; 522*66e63ce3Schristos 523*66e63ce3Schristos trace_input ("ld.w", OP_LOAD32, 4); 524*66e63ce3Schristos 525*66e63ce3Schristos adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); 526*66e63ce3Schristos adr &= ~0x3; 527*66e63ce3Schristos 528*66e63ce3Schristos State.regs[ OP[1] ] = load_mem (adr, 4); 529*66e63ce3Schristos 530*66e63ce3Schristos trace_output (OP_LOAD32); 531*66e63ce3Schristos 532*66e63ce3Schristos return 4; 533*66e63ce3Schristos } 534*66e63ce3Schristos 535*66e63ce3Schristos /* st.b */ 536*66e63ce3Schristos int 537*66e63ce3Schristos OP_740 () 538*66e63ce3Schristos { 539*66e63ce3Schristos trace_input ("st.b", OP_STORE32, 1); 540*66e63ce3Schristos 541*66e63ce3Schristos store_mem (State.regs[ OP[0] ] + EXTEND16 (OP[2]), 1, State.regs[ OP[1] ]); 542*66e63ce3Schristos 543*66e63ce3Schristos trace_output (OP_STORE32); 544*66e63ce3Schristos 545*66e63ce3Schristos return 4; 546*66e63ce3Schristos } 547*66e63ce3Schristos 548*66e63ce3Schristos /* st.h */ 549*66e63ce3Schristos int 550*66e63ce3Schristos OP_760 () 551*66e63ce3Schristos { 552*66e63ce3Schristos int adr; 553*66e63ce3Schristos 554*66e63ce3Schristos trace_input ("st.h", OP_STORE32, 2); 555*66e63ce3Schristos 556*66e63ce3Schristos adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]); 557*66e63ce3Schristos adr &= ~1; 558*66e63ce3Schristos 559*66e63ce3Schristos store_mem (adr, 2, State.regs[ OP[1] ]); 560*66e63ce3Schristos 561*66e63ce3Schristos trace_output (OP_STORE32); 562*66e63ce3Schristos 563*66e63ce3Schristos return 4; 564*66e63ce3Schristos } 565*66e63ce3Schristos 566*66e63ce3Schristos /* st.w */ 567*66e63ce3Schristos int 568*66e63ce3Schristos OP_10760 () 569*66e63ce3Schristos { 570*66e63ce3Schristos int adr; 571*66e63ce3Schristos 572*66e63ce3Schristos trace_input ("st.w", OP_STORE32, 4); 573*66e63ce3Schristos 574*66e63ce3Schristos adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); 575*66e63ce3Schristos adr &= ~3; 576*66e63ce3Schristos 577*66e63ce3Schristos store_mem (adr, 4, State.regs[ OP[1] ]); 578*66e63ce3Schristos 579*66e63ce3Schristos trace_output (OP_STORE32); 580*66e63ce3Schristos 581*66e63ce3Schristos return 4; 582*66e63ce3Schristos } 583*66e63ce3Schristos 584*66e63ce3Schristos /* add reg, reg */ 585*66e63ce3Schristos int 586*66e63ce3Schristos OP_1C0 () 587*66e63ce3Schristos { 588*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 589*66e63ce3Schristos 590*66e63ce3Schristos trace_input ("add", OP_REG_REG, 0); 591*66e63ce3Schristos 592*66e63ce3Schristos /* Compute the result. */ 593*66e63ce3Schristos 594*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 595*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 596*66e63ce3Schristos 597*66e63ce3Schristos result = op0 + op1; 598*66e63ce3Schristos 599*66e63ce3Schristos /* Compute the condition codes. */ 600*66e63ce3Schristos z = (result == 0); 601*66e63ce3Schristos s = (result & 0x80000000); 602*66e63ce3Schristos cy = (result < op0 || result < op1); 603*66e63ce3Schristos ov = ((op0 & 0x80000000) == (op1 & 0x80000000) 604*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 605*66e63ce3Schristos 606*66e63ce3Schristos /* Store the result and condition codes. */ 607*66e63ce3Schristos State.regs[OP[1]] = result; 608*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 609*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 610*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 611*66e63ce3Schristos trace_output (OP_REG_REG); 612*66e63ce3Schristos 613*66e63ce3Schristos return 2; 614*66e63ce3Schristos } 615*66e63ce3Schristos 616*66e63ce3Schristos /* add sign_extend(imm5), reg */ 617*66e63ce3Schristos int 618*66e63ce3Schristos OP_240 () 619*66e63ce3Schristos { 620*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 621*66e63ce3Schristos int temp; 622*66e63ce3Schristos 623*66e63ce3Schristos trace_input ("add", OP_IMM_REG, 0); 624*66e63ce3Schristos 625*66e63ce3Schristos /* Compute the result. */ 626*66e63ce3Schristos temp = SEXT5 (OP[0]); 627*66e63ce3Schristos op0 = temp; 628*66e63ce3Schristos op1 = State.regs[OP[1]]; 629*66e63ce3Schristos result = op0 + op1; 630*66e63ce3Schristos 631*66e63ce3Schristos /* Compute the condition codes. */ 632*66e63ce3Schristos z = (result == 0); 633*66e63ce3Schristos s = (result & 0x80000000); 634*66e63ce3Schristos cy = (result < op0 || result < op1); 635*66e63ce3Schristos ov = ((op0 & 0x80000000) == (op1 & 0x80000000) 636*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 637*66e63ce3Schristos 638*66e63ce3Schristos /* Store the result and condition codes. */ 639*66e63ce3Schristos State.regs[OP[1]] = result; 640*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 641*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 642*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 643*66e63ce3Schristos trace_output (OP_IMM_REG); 644*66e63ce3Schristos 645*66e63ce3Schristos return 2; 646*66e63ce3Schristos } 647*66e63ce3Schristos 648*66e63ce3Schristos /* addi sign_extend(imm16), reg, reg */ 649*66e63ce3Schristos int 650*66e63ce3Schristos OP_600 () 651*66e63ce3Schristos { 652*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 653*66e63ce3Schristos 654*66e63ce3Schristos trace_input ("addi", OP_IMM16_REG_REG, 0); 655*66e63ce3Schristos 656*66e63ce3Schristos /* Compute the result. */ 657*66e63ce3Schristos 658*66e63ce3Schristos op0 = EXTEND16 (OP[2]); 659*66e63ce3Schristos op1 = State.regs[ OP[0] ]; 660*66e63ce3Schristos result = op0 + op1; 661*66e63ce3Schristos 662*66e63ce3Schristos /* Compute the condition codes. */ 663*66e63ce3Schristos z = (result == 0); 664*66e63ce3Schristos s = (result & 0x80000000); 665*66e63ce3Schristos cy = (result < op0 || result < op1); 666*66e63ce3Schristos ov = ((op0 & 0x80000000) == (op1 & 0x80000000) 667*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 668*66e63ce3Schristos 669*66e63ce3Schristos /* Store the result and condition codes. */ 670*66e63ce3Schristos State.regs[OP[1]] = result; 671*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 672*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 673*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 674*66e63ce3Schristos trace_output (OP_IMM16_REG_REG); 675*66e63ce3Schristos 676*66e63ce3Schristos return 4; 677*66e63ce3Schristos } 678*66e63ce3Schristos 679*66e63ce3Schristos /* sub reg1, reg2 */ 680*66e63ce3Schristos int 681*66e63ce3Schristos OP_1A0 () 682*66e63ce3Schristos { 683*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 684*66e63ce3Schristos 685*66e63ce3Schristos trace_input ("sub", OP_REG_REG, 0); 686*66e63ce3Schristos /* Compute the result. */ 687*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 688*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 689*66e63ce3Schristos result = op1 - op0; 690*66e63ce3Schristos 691*66e63ce3Schristos /* Compute the condition codes. */ 692*66e63ce3Schristos z = (result == 0); 693*66e63ce3Schristos s = (result & 0x80000000); 694*66e63ce3Schristos cy = (op1 < op0); 695*66e63ce3Schristos ov = ((op1 & 0x80000000) != (op0 & 0x80000000) 696*66e63ce3Schristos && (op1 & 0x80000000) != (result & 0x80000000)); 697*66e63ce3Schristos 698*66e63ce3Schristos /* Store the result and condition codes. */ 699*66e63ce3Schristos State.regs[OP[1]] = result; 700*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 701*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 702*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 703*66e63ce3Schristos trace_output (OP_REG_REG); 704*66e63ce3Schristos 705*66e63ce3Schristos return 2; 706*66e63ce3Schristos } 707*66e63ce3Schristos 708*66e63ce3Schristos /* subr reg1, reg2 */ 709*66e63ce3Schristos int 710*66e63ce3Schristos OP_180 () 711*66e63ce3Schristos { 712*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 713*66e63ce3Schristos 714*66e63ce3Schristos trace_input ("subr", OP_REG_REG, 0); 715*66e63ce3Schristos /* Compute the result. */ 716*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 717*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 718*66e63ce3Schristos result = op0 - op1; 719*66e63ce3Schristos 720*66e63ce3Schristos /* Compute the condition codes. */ 721*66e63ce3Schristos z = (result == 0); 722*66e63ce3Schristos s = (result & 0x80000000); 723*66e63ce3Schristos cy = (op0 < op1); 724*66e63ce3Schristos ov = ((op0 & 0x80000000) != (op1 & 0x80000000) 725*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 726*66e63ce3Schristos 727*66e63ce3Schristos /* Store the result and condition codes. */ 728*66e63ce3Schristos State.regs[OP[1]] = result; 729*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 730*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 731*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 732*66e63ce3Schristos trace_output (OP_REG_REG); 733*66e63ce3Schristos 734*66e63ce3Schristos return 2; 735*66e63ce3Schristos } 736*66e63ce3Schristos 737*66e63ce3Schristos /* sxh reg1 */ 738*66e63ce3Schristos int 739*66e63ce3Schristos OP_E0 () 740*66e63ce3Schristos { 741*66e63ce3Schristos trace_input ("mulh", OP_REG_REG, 0); 742*66e63ce3Schristos 743*66e63ce3Schristos State.regs[ OP[1] ] = (EXTEND16 (State.regs[ OP[1] ]) * EXTEND16 (State.regs[ OP[0] ])); 744*66e63ce3Schristos 745*66e63ce3Schristos trace_output (OP_REG_REG); 746*66e63ce3Schristos 747*66e63ce3Schristos return 2; 748*66e63ce3Schristos } 749*66e63ce3Schristos 750*66e63ce3Schristos /* mulh sign_extend(imm5), reg2 */ 751*66e63ce3Schristos int 752*66e63ce3Schristos OP_2E0 () 753*66e63ce3Schristos { 754*66e63ce3Schristos trace_input ("mulh", OP_IMM_REG, 0); 755*66e63ce3Schristos 756*66e63ce3Schristos State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[1] ]) * SEXT5 (OP[0]); 757*66e63ce3Schristos 758*66e63ce3Schristos trace_output (OP_IMM_REG); 759*66e63ce3Schristos 760*66e63ce3Schristos return 2; 761*66e63ce3Schristos } 762*66e63ce3Schristos 763*66e63ce3Schristos /* mulhi imm16, reg1, reg2 */ 764*66e63ce3Schristos int 765*66e63ce3Schristos OP_6E0 () 766*66e63ce3Schristos { 767*66e63ce3Schristos trace_input ("mulhi", OP_IMM16_REG_REG, 0); 768*66e63ce3Schristos 769*66e63ce3Schristos State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[0] ]) * EXTEND16 (OP[2]); 770*66e63ce3Schristos 771*66e63ce3Schristos trace_output (OP_IMM16_REG_REG); 772*66e63ce3Schristos 773*66e63ce3Schristos return 4; 774*66e63ce3Schristos } 775*66e63ce3Schristos 776*66e63ce3Schristos /* cmp reg, reg */ 777*66e63ce3Schristos int 778*66e63ce3Schristos OP_1E0 () 779*66e63ce3Schristos { 780*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 781*66e63ce3Schristos 782*66e63ce3Schristos trace_input ("cmp", OP_REG_REG_CMP, 0); 783*66e63ce3Schristos /* Compute the result. */ 784*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 785*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 786*66e63ce3Schristos result = op1 - op0; 787*66e63ce3Schristos 788*66e63ce3Schristos /* Compute the condition codes. */ 789*66e63ce3Schristos z = (result == 0); 790*66e63ce3Schristos s = (result & 0x80000000); 791*66e63ce3Schristos cy = (op1 < op0); 792*66e63ce3Schristos ov = ((op1 & 0x80000000) != (op0 & 0x80000000) 793*66e63ce3Schristos && (op1 & 0x80000000) != (result & 0x80000000)); 794*66e63ce3Schristos 795*66e63ce3Schristos /* Set condition codes. */ 796*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 797*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 798*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 799*66e63ce3Schristos trace_output (OP_REG_REG_CMP); 800*66e63ce3Schristos 801*66e63ce3Schristos return 2; 802*66e63ce3Schristos } 803*66e63ce3Schristos 804*66e63ce3Schristos /* cmp sign_extend(imm5), reg */ 805*66e63ce3Schristos int 806*66e63ce3Schristos OP_260 () 807*66e63ce3Schristos { 808*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov; 809*66e63ce3Schristos int temp; 810*66e63ce3Schristos 811*66e63ce3Schristos /* Compute the result. */ 812*66e63ce3Schristos trace_input ("cmp", OP_IMM_REG_CMP, 0); 813*66e63ce3Schristos temp = SEXT5 (OP[0]); 814*66e63ce3Schristos op0 = temp; 815*66e63ce3Schristos op1 = State.regs[OP[1]]; 816*66e63ce3Schristos result = op1 - op0; 817*66e63ce3Schristos 818*66e63ce3Schristos /* Compute the condition codes. */ 819*66e63ce3Schristos z = (result == 0); 820*66e63ce3Schristos s = (result & 0x80000000); 821*66e63ce3Schristos cy = (op1 < op0); 822*66e63ce3Schristos ov = ((op1 & 0x80000000) != (op0 & 0x80000000) 823*66e63ce3Schristos && (op1 & 0x80000000) != (result & 0x80000000)); 824*66e63ce3Schristos 825*66e63ce3Schristos /* Set condition codes. */ 826*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 827*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 828*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); 829*66e63ce3Schristos trace_output (OP_IMM_REG_CMP); 830*66e63ce3Schristos 831*66e63ce3Schristos return 2; 832*66e63ce3Schristos } 833*66e63ce3Schristos 834*66e63ce3Schristos /* setf cccc,reg2 */ 835*66e63ce3Schristos int 836*66e63ce3Schristos OP_7E0 () 837*66e63ce3Schristos { 838*66e63ce3Schristos trace_input ("setf", OP_EX1, 0); 839*66e63ce3Schristos 840*66e63ce3Schristos State.regs[ OP[1] ] = condition_met (OP[0]); 841*66e63ce3Schristos 842*66e63ce3Schristos trace_output (OP_EX1); 843*66e63ce3Schristos 844*66e63ce3Schristos return 4; 845*66e63ce3Schristos } 846*66e63ce3Schristos 847*66e63ce3Schristos /* satadd reg,reg */ 848*66e63ce3Schristos int 849*66e63ce3Schristos OP_C0 () 850*66e63ce3Schristos { 851*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov, sat; 852*66e63ce3Schristos 853*66e63ce3Schristos trace_input ("satadd", OP_REG_REG, 0); 854*66e63ce3Schristos /* Compute the result. */ 855*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 856*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 857*66e63ce3Schristos result = op0 + op1; 858*66e63ce3Schristos 859*66e63ce3Schristos /* Compute the condition codes. */ 860*66e63ce3Schristos z = (result == 0); 861*66e63ce3Schristos s = (result & 0x80000000); 862*66e63ce3Schristos cy = (result < op0 || result < op1); 863*66e63ce3Schristos ov = ((op0 & 0x80000000) == (op1 & 0x80000000) 864*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 865*66e63ce3Schristos sat = ov; 866*66e63ce3Schristos 867*66e63ce3Schristos /* Handle saturated results. */ 868*66e63ce3Schristos if (sat && s) 869*66e63ce3Schristos { 870*66e63ce3Schristos /* An overflow that results in a negative result implies that we 871*66e63ce3Schristos became too positive. */ 872*66e63ce3Schristos result = 0x7fffffff; 873*66e63ce3Schristos s = 0; 874*66e63ce3Schristos } 875*66e63ce3Schristos else if (sat) 876*66e63ce3Schristos { 877*66e63ce3Schristos /* Any other overflow must have thus been too negative. */ 878*66e63ce3Schristos result = 0x80000000; 879*66e63ce3Schristos s = 1; 880*66e63ce3Schristos z = 0; 881*66e63ce3Schristos } 882*66e63ce3Schristos 883*66e63ce3Schristos /* Store the result and condition codes. */ 884*66e63ce3Schristos State.regs[OP[1]] = result; 885*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 886*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 887*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) 888*66e63ce3Schristos | (sat ? PSW_SAT : 0)); 889*66e63ce3Schristos 890*66e63ce3Schristos trace_output (OP_REG_REG); 891*66e63ce3Schristos 892*66e63ce3Schristos return 2; 893*66e63ce3Schristos } 894*66e63ce3Schristos 895*66e63ce3Schristos /* satadd sign_extend(imm5), reg */ 896*66e63ce3Schristos int 897*66e63ce3Schristos OP_220 () 898*66e63ce3Schristos { 899*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov, sat; 900*66e63ce3Schristos 901*66e63ce3Schristos int temp; 902*66e63ce3Schristos 903*66e63ce3Schristos trace_input ("satadd", OP_IMM_REG, 0); 904*66e63ce3Schristos 905*66e63ce3Schristos /* Compute the result. */ 906*66e63ce3Schristos temp = SEXT5 (OP[0]); 907*66e63ce3Schristos op0 = temp; 908*66e63ce3Schristos op1 = State.regs[OP[1]]; 909*66e63ce3Schristos result = op0 + op1; 910*66e63ce3Schristos 911*66e63ce3Schristos /* Compute the condition codes. */ 912*66e63ce3Schristos z = (result == 0); 913*66e63ce3Schristos s = (result & 0x80000000); 914*66e63ce3Schristos cy = (result < op0 || result < op1); 915*66e63ce3Schristos ov = ((op0 & 0x80000000) == (op1 & 0x80000000) 916*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 917*66e63ce3Schristos sat = ov; 918*66e63ce3Schristos 919*66e63ce3Schristos /* Handle saturated results. */ 920*66e63ce3Schristos if (sat && s) 921*66e63ce3Schristos { 922*66e63ce3Schristos /* An overflow that results in a negative result implies that we 923*66e63ce3Schristos became too positive. */ 924*66e63ce3Schristos result = 0x7fffffff; 925*66e63ce3Schristos s = 0; 926*66e63ce3Schristos } 927*66e63ce3Schristos else if (sat) 928*66e63ce3Schristos { 929*66e63ce3Schristos /* Any other overflow must have thus been too negative. */ 930*66e63ce3Schristos result = 0x80000000; 931*66e63ce3Schristos s = 1; 932*66e63ce3Schristos z = 0; 933*66e63ce3Schristos } 934*66e63ce3Schristos 935*66e63ce3Schristos /* Store the result and condition codes. */ 936*66e63ce3Schristos State.regs[OP[1]] = result; 937*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 938*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 939*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) 940*66e63ce3Schristos | (sat ? PSW_SAT : 0)); 941*66e63ce3Schristos trace_output (OP_IMM_REG); 942*66e63ce3Schristos 943*66e63ce3Schristos return 2; 944*66e63ce3Schristos } 945*66e63ce3Schristos 946*66e63ce3Schristos /* satsub reg1, reg2 */ 947*66e63ce3Schristos int 948*66e63ce3Schristos OP_A0 () 949*66e63ce3Schristos { 950*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov, sat; 951*66e63ce3Schristos 952*66e63ce3Schristos trace_input ("satsub", OP_REG_REG, 0); 953*66e63ce3Schristos 954*66e63ce3Schristos /* Compute the result. */ 955*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 956*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 957*66e63ce3Schristos result = op1 - op0; 958*66e63ce3Schristos 959*66e63ce3Schristos /* Compute the condition codes. */ 960*66e63ce3Schristos z = (result == 0); 961*66e63ce3Schristos s = (result & 0x80000000); 962*66e63ce3Schristos cy = (op1 < op0); 963*66e63ce3Schristos ov = ((op1 & 0x80000000) != (op0 & 0x80000000) 964*66e63ce3Schristos && (op1 & 0x80000000) != (result & 0x80000000)); 965*66e63ce3Schristos sat = ov; 966*66e63ce3Schristos 967*66e63ce3Schristos /* Handle saturated results. */ 968*66e63ce3Schristos if (sat && s) 969*66e63ce3Schristos { 970*66e63ce3Schristos /* An overflow that results in a negative result implies that we 971*66e63ce3Schristos became too positive. */ 972*66e63ce3Schristos result = 0x7fffffff; 973*66e63ce3Schristos s = 0; 974*66e63ce3Schristos } 975*66e63ce3Schristos else if (sat) 976*66e63ce3Schristos { 977*66e63ce3Schristos /* Any other overflow must have thus been too negative. */ 978*66e63ce3Schristos result = 0x80000000; 979*66e63ce3Schristos s = 1; 980*66e63ce3Schristos z = 0; 981*66e63ce3Schristos } 982*66e63ce3Schristos 983*66e63ce3Schristos /* Store the result and condition codes. */ 984*66e63ce3Schristos State.regs[OP[1]] = result; 985*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 986*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 987*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) 988*66e63ce3Schristos | (sat ? PSW_SAT : 0)); 989*66e63ce3Schristos 990*66e63ce3Schristos trace_output (OP_REG_REG); 991*66e63ce3Schristos return 2; 992*66e63ce3Schristos } 993*66e63ce3Schristos 994*66e63ce3Schristos /* satsubi sign_extend(imm16), reg */ 995*66e63ce3Schristos int 996*66e63ce3Schristos OP_660 () 997*66e63ce3Schristos { 998*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov, sat; 999*66e63ce3Schristos int temp; 1000*66e63ce3Schristos 1001*66e63ce3Schristos trace_input ("satsubi", OP_IMM_REG, 0); 1002*66e63ce3Schristos 1003*66e63ce3Schristos /* Compute the result. */ 1004*66e63ce3Schristos temp = EXTEND16 (OP[2]); 1005*66e63ce3Schristos op0 = temp; 1006*66e63ce3Schristos op1 = State.regs[ OP[0] ]; 1007*66e63ce3Schristos result = op1 - op0; 1008*66e63ce3Schristos 1009*66e63ce3Schristos /* Compute the condition codes. */ 1010*66e63ce3Schristos z = (result == 0); 1011*66e63ce3Schristos s = (result & 0x80000000); 1012*66e63ce3Schristos cy = (op1 < op0); 1013*66e63ce3Schristos ov = ((op1 & 0x80000000) != (op0 & 0x80000000) 1014*66e63ce3Schristos && (op1 & 0x80000000) != (result & 0x80000000)); 1015*66e63ce3Schristos sat = ov; 1016*66e63ce3Schristos 1017*66e63ce3Schristos /* Handle saturated results. */ 1018*66e63ce3Schristos if (sat && s) 1019*66e63ce3Schristos { 1020*66e63ce3Schristos /* An overflow that results in a negative result implies that we 1021*66e63ce3Schristos became too positive. */ 1022*66e63ce3Schristos result = 0x7fffffff; 1023*66e63ce3Schristos s = 0; 1024*66e63ce3Schristos } 1025*66e63ce3Schristos else if (sat) 1026*66e63ce3Schristos { 1027*66e63ce3Schristos /* Any other overflow must have thus been too negative. */ 1028*66e63ce3Schristos result = 0x80000000; 1029*66e63ce3Schristos s = 1; 1030*66e63ce3Schristos z = 0; 1031*66e63ce3Schristos } 1032*66e63ce3Schristos 1033*66e63ce3Schristos /* Store the result and condition codes. */ 1034*66e63ce3Schristos State.regs[OP[1]] = result; 1035*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 1036*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1037*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) 1038*66e63ce3Schristos | (sat ? PSW_SAT : 0)); 1039*66e63ce3Schristos 1040*66e63ce3Schristos trace_output (OP_IMM_REG); 1041*66e63ce3Schristos 1042*66e63ce3Schristos return 4; 1043*66e63ce3Schristos } 1044*66e63ce3Schristos 1045*66e63ce3Schristos /* satsubr reg,reg */ 1046*66e63ce3Schristos int 1047*66e63ce3Schristos OP_80 () 1048*66e63ce3Schristos { 1049*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy, ov, sat; 1050*66e63ce3Schristos 1051*66e63ce3Schristos trace_input ("satsubr", OP_REG_REG, 0); 1052*66e63ce3Schristos 1053*66e63ce3Schristos /* Compute the result. */ 1054*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1055*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1056*66e63ce3Schristos result = op0 - op1; 1057*66e63ce3Schristos 1058*66e63ce3Schristos /* Compute the condition codes. */ 1059*66e63ce3Schristos z = (result == 0); 1060*66e63ce3Schristos s = (result & 0x80000000); 1061*66e63ce3Schristos cy = (op0 < op1); 1062*66e63ce3Schristos ov = ((op0 & 0x80000000) != (op1 & 0x80000000) 1063*66e63ce3Schristos && (op0 & 0x80000000) != (result & 0x80000000)); 1064*66e63ce3Schristos sat = ov; 1065*66e63ce3Schristos 1066*66e63ce3Schristos /* Handle saturated results. */ 1067*66e63ce3Schristos if (sat && s) 1068*66e63ce3Schristos { 1069*66e63ce3Schristos /* An overflow that results in a negative result implies that we 1070*66e63ce3Schristos became too positive. */ 1071*66e63ce3Schristos result = 0x7fffffff; 1072*66e63ce3Schristos s = 0; 1073*66e63ce3Schristos } 1074*66e63ce3Schristos else if (sat) 1075*66e63ce3Schristos { 1076*66e63ce3Schristos /* Any other overflow must have thus been too negative. */ 1077*66e63ce3Schristos result = 0x80000000; 1078*66e63ce3Schristos s = 1; 1079*66e63ce3Schristos z = 0; 1080*66e63ce3Schristos } 1081*66e63ce3Schristos 1082*66e63ce3Schristos /* Store the result and condition codes. */ 1083*66e63ce3Schristos State.regs[OP[1]] = result; 1084*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); 1085*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1086*66e63ce3Schristos | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) 1087*66e63ce3Schristos | (sat ? PSW_SAT : 0)); 1088*66e63ce3Schristos 1089*66e63ce3Schristos trace_output (OP_REG_REG); 1090*66e63ce3Schristos 1091*66e63ce3Schristos return 2; 1092*66e63ce3Schristos } 1093*66e63ce3Schristos 1094*66e63ce3Schristos /* tst reg,reg */ 1095*66e63ce3Schristos int 1096*66e63ce3Schristos OP_160 () 1097*66e63ce3Schristos { 1098*66e63ce3Schristos unsigned int op0, op1, result, z, s; 1099*66e63ce3Schristos 1100*66e63ce3Schristos trace_input ("tst", OP_REG_REG_CMP, 0); 1101*66e63ce3Schristos 1102*66e63ce3Schristos /* Compute the result. */ 1103*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1104*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1105*66e63ce3Schristos result = op0 & op1; 1106*66e63ce3Schristos 1107*66e63ce3Schristos /* Compute the condition codes. */ 1108*66e63ce3Schristos z = (result == 0); 1109*66e63ce3Schristos s = (result & 0x80000000); 1110*66e63ce3Schristos 1111*66e63ce3Schristos /* Store the condition codes. */ 1112*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1113*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1114*66e63ce3Schristos trace_output (OP_REG_REG_CMP); 1115*66e63ce3Schristos 1116*66e63ce3Schristos return 2; 1117*66e63ce3Schristos } 1118*66e63ce3Schristos 1119*66e63ce3Schristos /* mov sign_extend(imm5), reg */ 1120*66e63ce3Schristos int 1121*66e63ce3Schristos OP_200 () 1122*66e63ce3Schristos { 1123*66e63ce3Schristos int value = SEXT5 (OP[0]); 1124*66e63ce3Schristos 1125*66e63ce3Schristos trace_input ("mov", OP_IMM_REG_MOVE, 0); 1126*66e63ce3Schristos 1127*66e63ce3Schristos State.regs[ OP[1] ] = value; 1128*66e63ce3Schristos 1129*66e63ce3Schristos trace_output (OP_IMM_REG_MOVE); 1130*66e63ce3Schristos 1131*66e63ce3Schristos return 2; 1132*66e63ce3Schristos } 1133*66e63ce3Schristos 1134*66e63ce3Schristos /* movhi imm16, reg, reg */ 1135*66e63ce3Schristos int 1136*66e63ce3Schristos OP_640 () 1137*66e63ce3Schristos { 1138*66e63ce3Schristos trace_input ("movhi", OP_UIMM16_REG_REG, 16); 1139*66e63ce3Schristos 1140*66e63ce3Schristos State.regs[ OP[1] ] = State.regs[ OP[0] ] + (OP[2] << 16); 1141*66e63ce3Schristos 1142*66e63ce3Schristos trace_output (OP_UIMM16_REG_REG); 1143*66e63ce3Schristos 1144*66e63ce3Schristos return 4; 1145*66e63ce3Schristos } 1146*66e63ce3Schristos 1147*66e63ce3Schristos /* sar zero_extend(imm5),reg1 */ 1148*66e63ce3Schristos int 1149*66e63ce3Schristos OP_2A0 () 1150*66e63ce3Schristos { 1151*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy; 1152*66e63ce3Schristos 1153*66e63ce3Schristos trace_input ("sar", OP_IMM_REG, 0); 1154*66e63ce3Schristos op0 = OP[0]; 1155*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1156*66e63ce3Schristos result = (signed)op1 >> op0; 1157*66e63ce3Schristos 1158*66e63ce3Schristos /* Compute the condition codes. */ 1159*66e63ce3Schristos z = (result == 0); 1160*66e63ce3Schristos s = (result & 0x80000000); 1161*66e63ce3Schristos cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; 1162*66e63ce3Schristos 1163*66e63ce3Schristos /* Store the result and condition codes. */ 1164*66e63ce3Schristos State.regs[ OP[1] ] = result; 1165*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); 1166*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1167*66e63ce3Schristos | (cy ? PSW_CY : 0)); 1168*66e63ce3Schristos trace_output (OP_IMM_REG); 1169*66e63ce3Schristos 1170*66e63ce3Schristos return 2; 1171*66e63ce3Schristos } 1172*66e63ce3Schristos 1173*66e63ce3Schristos /* sar reg1, reg2 */ 1174*66e63ce3Schristos int 1175*66e63ce3Schristos OP_A007E0 () 1176*66e63ce3Schristos { 1177*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy; 1178*66e63ce3Schristos 1179*66e63ce3Schristos trace_input ("sar", OP_REG_REG, 0); 1180*66e63ce3Schristos 1181*66e63ce3Schristos op0 = State.regs[ OP[0] ] & 0x1f; 1182*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1183*66e63ce3Schristos result = (signed)op1 >> op0; 1184*66e63ce3Schristos 1185*66e63ce3Schristos /* Compute the condition codes. */ 1186*66e63ce3Schristos z = (result == 0); 1187*66e63ce3Schristos s = (result & 0x80000000); 1188*66e63ce3Schristos cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; 1189*66e63ce3Schristos 1190*66e63ce3Schristos /* Store the result and condition codes. */ 1191*66e63ce3Schristos State.regs[OP[1]] = result; 1192*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); 1193*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1194*66e63ce3Schristos | (cy ? PSW_CY : 0)); 1195*66e63ce3Schristos trace_output (OP_REG_REG); 1196*66e63ce3Schristos 1197*66e63ce3Schristos return 4; 1198*66e63ce3Schristos } 1199*66e63ce3Schristos 1200*66e63ce3Schristos /* shl zero_extend(imm5),reg1 */ 1201*66e63ce3Schristos int 1202*66e63ce3Schristos OP_2C0 () 1203*66e63ce3Schristos { 1204*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy; 1205*66e63ce3Schristos 1206*66e63ce3Schristos trace_input ("shl", OP_IMM_REG, 0); 1207*66e63ce3Schristos op0 = OP[0]; 1208*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1209*66e63ce3Schristos result = op1 << op0; 1210*66e63ce3Schristos 1211*66e63ce3Schristos /* Compute the condition codes. */ 1212*66e63ce3Schristos z = (result == 0); 1213*66e63ce3Schristos s = (result & 0x80000000); 1214*66e63ce3Schristos cy = op0 ? (op1 & (1 << (32 - op0))) : 0; 1215*66e63ce3Schristos 1216*66e63ce3Schristos /* Store the result and condition codes. */ 1217*66e63ce3Schristos State.regs[OP[1]] = result; 1218*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); 1219*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1220*66e63ce3Schristos | (cy ? PSW_CY : 0)); 1221*66e63ce3Schristos trace_output (OP_IMM_REG); 1222*66e63ce3Schristos 1223*66e63ce3Schristos return 2; 1224*66e63ce3Schristos } 1225*66e63ce3Schristos 1226*66e63ce3Schristos /* shl reg1, reg2 */ 1227*66e63ce3Schristos int 1228*66e63ce3Schristos OP_C007E0 () 1229*66e63ce3Schristos { 1230*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy; 1231*66e63ce3Schristos 1232*66e63ce3Schristos trace_input ("shl", OP_REG_REG, 0); 1233*66e63ce3Schristos op0 = State.regs[ OP[0] ] & 0x1f; 1234*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1235*66e63ce3Schristos result = op1 << op0; 1236*66e63ce3Schristos 1237*66e63ce3Schristos /* Compute the condition codes. */ 1238*66e63ce3Schristos z = (result == 0); 1239*66e63ce3Schristos s = (result & 0x80000000); 1240*66e63ce3Schristos cy = op0 ? (op1 & (1 << (32 - op0))) : 0; 1241*66e63ce3Schristos 1242*66e63ce3Schristos /* Store the result and condition codes. */ 1243*66e63ce3Schristos State.regs[OP[1]] = result; 1244*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); 1245*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1246*66e63ce3Schristos | (cy ? PSW_CY : 0)); 1247*66e63ce3Schristos trace_output (OP_REG_REG); 1248*66e63ce3Schristos 1249*66e63ce3Schristos return 4; 1250*66e63ce3Schristos } 1251*66e63ce3Schristos 1252*66e63ce3Schristos /* shr zero_extend(imm5),reg1 */ 1253*66e63ce3Schristos int 1254*66e63ce3Schristos OP_280 () 1255*66e63ce3Schristos { 1256*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy; 1257*66e63ce3Schristos 1258*66e63ce3Schristos trace_input ("shr", OP_IMM_REG, 0); 1259*66e63ce3Schristos op0 = OP[0]; 1260*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1261*66e63ce3Schristos result = op1 >> op0; 1262*66e63ce3Schristos 1263*66e63ce3Schristos /* Compute the condition codes. */ 1264*66e63ce3Schristos z = (result == 0); 1265*66e63ce3Schristos s = (result & 0x80000000); 1266*66e63ce3Schristos cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; 1267*66e63ce3Schristos 1268*66e63ce3Schristos /* Store the result and condition codes. */ 1269*66e63ce3Schristos State.regs[OP[1]] = result; 1270*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); 1271*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1272*66e63ce3Schristos | (cy ? PSW_CY : 0)); 1273*66e63ce3Schristos trace_output (OP_IMM_REG); 1274*66e63ce3Schristos 1275*66e63ce3Schristos return 2; 1276*66e63ce3Schristos } 1277*66e63ce3Schristos 1278*66e63ce3Schristos /* shr reg1, reg2 */ 1279*66e63ce3Schristos int 1280*66e63ce3Schristos OP_8007E0 () 1281*66e63ce3Schristos { 1282*66e63ce3Schristos unsigned int op0, op1, result, z, s, cy; 1283*66e63ce3Schristos 1284*66e63ce3Schristos trace_input ("shr", OP_REG_REG, 0); 1285*66e63ce3Schristos op0 = State.regs[ OP[0] ] & 0x1f; 1286*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1287*66e63ce3Schristos result = op1 >> op0; 1288*66e63ce3Schristos 1289*66e63ce3Schristos /* Compute the condition codes. */ 1290*66e63ce3Schristos z = (result == 0); 1291*66e63ce3Schristos s = (result & 0x80000000); 1292*66e63ce3Schristos cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; 1293*66e63ce3Schristos 1294*66e63ce3Schristos /* Store the result and condition codes. */ 1295*66e63ce3Schristos State.regs[OP[1]] = result; 1296*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); 1297*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) 1298*66e63ce3Schristos | (cy ? PSW_CY : 0)); 1299*66e63ce3Schristos trace_output (OP_REG_REG); 1300*66e63ce3Schristos 1301*66e63ce3Schristos return 4; 1302*66e63ce3Schristos } 1303*66e63ce3Schristos 1304*66e63ce3Schristos /* or reg, reg */ 1305*66e63ce3Schristos int 1306*66e63ce3Schristos OP_100 () 1307*66e63ce3Schristos { 1308*66e63ce3Schristos unsigned int op0, op1, result, z, s; 1309*66e63ce3Schristos 1310*66e63ce3Schristos trace_input ("or", OP_REG_REG, 0); 1311*66e63ce3Schristos 1312*66e63ce3Schristos /* Compute the result. */ 1313*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1314*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1315*66e63ce3Schristos result = op0 | op1; 1316*66e63ce3Schristos 1317*66e63ce3Schristos /* Compute the condition codes. */ 1318*66e63ce3Schristos z = (result == 0); 1319*66e63ce3Schristos s = (result & 0x80000000); 1320*66e63ce3Schristos 1321*66e63ce3Schristos /* Store the result and condition codes. */ 1322*66e63ce3Schristos State.regs[OP[1]] = result; 1323*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1324*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1325*66e63ce3Schristos trace_output (OP_REG_REG); 1326*66e63ce3Schristos 1327*66e63ce3Schristos return 2; 1328*66e63ce3Schristos } 1329*66e63ce3Schristos 1330*66e63ce3Schristos /* ori zero_extend(imm16), reg, reg */ 1331*66e63ce3Schristos int 1332*66e63ce3Schristos OP_680 () 1333*66e63ce3Schristos { 1334*66e63ce3Schristos unsigned int op0, op1, result, z, s; 1335*66e63ce3Schristos 1336*66e63ce3Schristos trace_input ("ori", OP_UIMM16_REG_REG, 0); 1337*66e63ce3Schristos op0 = OP[2]; 1338*66e63ce3Schristos op1 = State.regs[ OP[0] ]; 1339*66e63ce3Schristos result = op0 | op1; 1340*66e63ce3Schristos 1341*66e63ce3Schristos /* Compute the condition codes. */ 1342*66e63ce3Schristos z = (result == 0); 1343*66e63ce3Schristos s = (result & 0x80000000); 1344*66e63ce3Schristos 1345*66e63ce3Schristos /* Store the result and condition codes. */ 1346*66e63ce3Schristos State.regs[OP[1]] = result; 1347*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1348*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1349*66e63ce3Schristos trace_output (OP_UIMM16_REG_REG); 1350*66e63ce3Schristos 1351*66e63ce3Schristos return 4; 1352*66e63ce3Schristos } 1353*66e63ce3Schristos 1354*66e63ce3Schristos /* and reg, reg */ 1355*66e63ce3Schristos int 1356*66e63ce3Schristos OP_140 () 1357*66e63ce3Schristos { 1358*66e63ce3Schristos unsigned int op0, op1, result, z, s; 1359*66e63ce3Schristos 1360*66e63ce3Schristos trace_input ("and", OP_REG_REG, 0); 1361*66e63ce3Schristos 1362*66e63ce3Schristos /* Compute the result. */ 1363*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1364*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1365*66e63ce3Schristos result = op0 & op1; 1366*66e63ce3Schristos 1367*66e63ce3Schristos /* Compute the condition codes. */ 1368*66e63ce3Schristos z = (result == 0); 1369*66e63ce3Schristos s = (result & 0x80000000); 1370*66e63ce3Schristos 1371*66e63ce3Schristos /* Store the result and condition codes. */ 1372*66e63ce3Schristos State.regs[OP[1]] = result; 1373*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1374*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1375*66e63ce3Schristos trace_output (OP_REG_REG); 1376*66e63ce3Schristos 1377*66e63ce3Schristos return 2; 1378*66e63ce3Schristos } 1379*66e63ce3Schristos 1380*66e63ce3Schristos /* andi zero_extend(imm16), reg, reg */ 1381*66e63ce3Schristos int 1382*66e63ce3Schristos OP_6C0 () 1383*66e63ce3Schristos { 1384*66e63ce3Schristos unsigned int result, z; 1385*66e63ce3Schristos 1386*66e63ce3Schristos trace_input ("andi", OP_UIMM16_REG_REG, 0); 1387*66e63ce3Schristos 1388*66e63ce3Schristos result = OP[2] & State.regs[ OP[0] ]; 1389*66e63ce3Schristos 1390*66e63ce3Schristos /* Compute the condition codes. */ 1391*66e63ce3Schristos z = (result == 0); 1392*66e63ce3Schristos 1393*66e63ce3Schristos /* Store the result and condition codes. */ 1394*66e63ce3Schristos State.regs[ OP[1] ] = result; 1395*66e63ce3Schristos 1396*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1397*66e63ce3Schristos PSW |= (z ? PSW_Z : 0); 1398*66e63ce3Schristos 1399*66e63ce3Schristos trace_output (OP_UIMM16_REG_REG); 1400*66e63ce3Schristos 1401*66e63ce3Schristos return 4; 1402*66e63ce3Schristos } 1403*66e63ce3Schristos 1404*66e63ce3Schristos /* xor reg, reg */ 1405*66e63ce3Schristos int 1406*66e63ce3Schristos OP_120 () 1407*66e63ce3Schristos { 1408*66e63ce3Schristos unsigned int op0, op1, result, z, s; 1409*66e63ce3Schristos 1410*66e63ce3Schristos trace_input ("xor", OP_REG_REG, 0); 1411*66e63ce3Schristos 1412*66e63ce3Schristos /* Compute the result. */ 1413*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1414*66e63ce3Schristos op1 = State.regs[ OP[1] ]; 1415*66e63ce3Schristos result = op0 ^ op1; 1416*66e63ce3Schristos 1417*66e63ce3Schristos /* Compute the condition codes. */ 1418*66e63ce3Schristos z = (result == 0); 1419*66e63ce3Schristos s = (result & 0x80000000); 1420*66e63ce3Schristos 1421*66e63ce3Schristos /* Store the result and condition codes. */ 1422*66e63ce3Schristos State.regs[OP[1]] = result; 1423*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1424*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1425*66e63ce3Schristos trace_output (OP_REG_REG); 1426*66e63ce3Schristos 1427*66e63ce3Schristos return 2; 1428*66e63ce3Schristos } 1429*66e63ce3Schristos 1430*66e63ce3Schristos /* xori zero_extend(imm16), reg, reg */ 1431*66e63ce3Schristos int 1432*66e63ce3Schristos OP_6A0 () 1433*66e63ce3Schristos { 1434*66e63ce3Schristos unsigned int op0, op1, result, z, s; 1435*66e63ce3Schristos 1436*66e63ce3Schristos trace_input ("xori", OP_UIMM16_REG_REG, 0); 1437*66e63ce3Schristos op0 = OP[2]; 1438*66e63ce3Schristos op1 = State.regs[ OP[0] ]; 1439*66e63ce3Schristos result = op0 ^ op1; 1440*66e63ce3Schristos 1441*66e63ce3Schristos /* Compute the condition codes. */ 1442*66e63ce3Schristos z = (result == 0); 1443*66e63ce3Schristos s = (result & 0x80000000); 1444*66e63ce3Schristos 1445*66e63ce3Schristos /* Store the result and condition codes. */ 1446*66e63ce3Schristos State.regs[OP[1]] = result; 1447*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1448*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1449*66e63ce3Schristos trace_output (OP_UIMM16_REG_REG); 1450*66e63ce3Schristos 1451*66e63ce3Schristos return 4; 1452*66e63ce3Schristos } 1453*66e63ce3Schristos 1454*66e63ce3Schristos /* not reg1, reg2 */ 1455*66e63ce3Schristos int 1456*66e63ce3Schristos OP_20 () 1457*66e63ce3Schristos { 1458*66e63ce3Schristos unsigned int op0, result, z, s; 1459*66e63ce3Schristos 1460*66e63ce3Schristos trace_input ("not", OP_REG_REG_MOVE, 0); 1461*66e63ce3Schristos /* Compute the result. */ 1462*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1463*66e63ce3Schristos result = ~op0; 1464*66e63ce3Schristos 1465*66e63ce3Schristos /* Compute the condition codes. */ 1466*66e63ce3Schristos z = (result == 0); 1467*66e63ce3Schristos s = (result & 0x80000000); 1468*66e63ce3Schristos 1469*66e63ce3Schristos /* Store the result and condition codes. */ 1470*66e63ce3Schristos State.regs[OP[1]] = result; 1471*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 1472*66e63ce3Schristos PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); 1473*66e63ce3Schristos trace_output (OP_REG_REG_MOVE); 1474*66e63ce3Schristos 1475*66e63ce3Schristos return 2; 1476*66e63ce3Schristos } 1477*66e63ce3Schristos 1478*66e63ce3Schristos /* set1 */ 1479*66e63ce3Schristos int 1480*66e63ce3Schristos OP_7C0 () 1481*66e63ce3Schristos { 1482*66e63ce3Schristos unsigned int op0, op1, op2; 1483*66e63ce3Schristos int temp; 1484*66e63ce3Schristos 1485*66e63ce3Schristos trace_input ("set1", OP_BIT, 0); 1486*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1487*66e63ce3Schristos op1 = OP[1] & 0x7; 1488*66e63ce3Schristos temp = EXTEND16 (OP[2]); 1489*66e63ce3Schristos op2 = temp; 1490*66e63ce3Schristos temp = load_mem (op0 + op2, 1); 1491*66e63ce3Schristos PSW &= ~PSW_Z; 1492*66e63ce3Schristos if ((temp & (1 << op1)) == 0) 1493*66e63ce3Schristos PSW |= PSW_Z; 1494*66e63ce3Schristos temp |= (1 << op1); 1495*66e63ce3Schristos store_mem (op0 + op2, 1, temp); 1496*66e63ce3Schristos trace_output (OP_BIT); 1497*66e63ce3Schristos 1498*66e63ce3Schristos return 4; 1499*66e63ce3Schristos } 1500*66e63ce3Schristos 1501*66e63ce3Schristos /* not1 */ 1502*66e63ce3Schristos int 1503*66e63ce3Schristos OP_47C0 () 1504*66e63ce3Schristos { 1505*66e63ce3Schristos unsigned int op0, op1, op2; 1506*66e63ce3Schristos int temp; 1507*66e63ce3Schristos 1508*66e63ce3Schristos trace_input ("not1", OP_BIT, 0); 1509*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1510*66e63ce3Schristos op1 = OP[1] & 0x7; 1511*66e63ce3Schristos temp = EXTEND16 (OP[2]); 1512*66e63ce3Schristos op2 = temp; 1513*66e63ce3Schristos temp = load_mem (op0 + op2, 1); 1514*66e63ce3Schristos PSW &= ~PSW_Z; 1515*66e63ce3Schristos if ((temp & (1 << op1)) == 0) 1516*66e63ce3Schristos PSW |= PSW_Z; 1517*66e63ce3Schristos temp ^= (1 << op1); 1518*66e63ce3Schristos store_mem (op0 + op2, 1, temp); 1519*66e63ce3Schristos trace_output (OP_BIT); 1520*66e63ce3Schristos 1521*66e63ce3Schristos return 4; 1522*66e63ce3Schristos } 1523*66e63ce3Schristos 1524*66e63ce3Schristos /* clr1 */ 1525*66e63ce3Schristos int 1526*66e63ce3Schristos OP_87C0 () 1527*66e63ce3Schristos { 1528*66e63ce3Schristos unsigned int op0, op1, op2; 1529*66e63ce3Schristos int temp; 1530*66e63ce3Schristos 1531*66e63ce3Schristos trace_input ("clr1", OP_BIT, 0); 1532*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1533*66e63ce3Schristos op1 = OP[1] & 0x7; 1534*66e63ce3Schristos temp = EXTEND16 (OP[2]); 1535*66e63ce3Schristos op2 = temp; 1536*66e63ce3Schristos temp = load_mem (op0 + op2, 1); 1537*66e63ce3Schristos PSW &= ~PSW_Z; 1538*66e63ce3Schristos if ((temp & (1 << op1)) == 0) 1539*66e63ce3Schristos PSW |= PSW_Z; 1540*66e63ce3Schristos temp &= ~(1 << op1); 1541*66e63ce3Schristos store_mem (op0 + op2, 1, temp); 1542*66e63ce3Schristos trace_output (OP_BIT); 1543*66e63ce3Schristos 1544*66e63ce3Schristos return 4; 1545*66e63ce3Schristos } 1546*66e63ce3Schristos 1547*66e63ce3Schristos /* tst1 */ 1548*66e63ce3Schristos int 1549*66e63ce3Schristos OP_C7C0 () 1550*66e63ce3Schristos { 1551*66e63ce3Schristos unsigned int op0, op1, op2; 1552*66e63ce3Schristos int temp; 1553*66e63ce3Schristos 1554*66e63ce3Schristos trace_input ("tst1", OP_BIT, 0); 1555*66e63ce3Schristos op0 = State.regs[ OP[0] ]; 1556*66e63ce3Schristos op1 = OP[1] & 0x7; 1557*66e63ce3Schristos temp = EXTEND16 (OP[2]); 1558*66e63ce3Schristos op2 = temp; 1559*66e63ce3Schristos temp = load_mem (op0 + op2, 1); 1560*66e63ce3Schristos PSW &= ~PSW_Z; 1561*66e63ce3Schristos if ((temp & (1 << op1)) == 0) 1562*66e63ce3Schristos PSW |= PSW_Z; 1563*66e63ce3Schristos trace_output (OP_BIT); 1564*66e63ce3Schristos 1565*66e63ce3Schristos return 4; 1566*66e63ce3Schristos } 1567*66e63ce3Schristos 1568*66e63ce3Schristos /* di */ 1569*66e63ce3Schristos int 1570*66e63ce3Schristos OP_16007E0 () 1571*66e63ce3Schristos { 1572*66e63ce3Schristos trace_input ("di", OP_NONE, 0); 1573*66e63ce3Schristos PSW |= PSW_ID; 1574*66e63ce3Schristos trace_output (OP_NONE); 1575*66e63ce3Schristos 1576*66e63ce3Schristos return 4; 1577*66e63ce3Schristos } 1578*66e63ce3Schristos 1579*66e63ce3Schristos /* ei */ 1580*66e63ce3Schristos int 1581*66e63ce3Schristos OP_16087E0 () 1582*66e63ce3Schristos { 1583*66e63ce3Schristos trace_input ("ei", OP_NONE, 0); 1584*66e63ce3Schristos PSW &= ~PSW_ID; 1585*66e63ce3Schristos trace_output (OP_NONE); 1586*66e63ce3Schristos 1587*66e63ce3Schristos return 4; 1588*66e63ce3Schristos } 1589*66e63ce3Schristos 1590*66e63ce3Schristos /* halt */ 1591*66e63ce3Schristos int 1592*66e63ce3Schristos OP_12007E0 () 1593*66e63ce3Schristos { 1594*66e63ce3Schristos trace_input ("halt", OP_NONE, 0); 1595*66e63ce3Schristos /* FIXME this should put processor into a mode where NMI still handled */ 1596*66e63ce3Schristos trace_output (OP_NONE); 1597*66e63ce3Schristos sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, 1598*66e63ce3Schristos sim_stopped, SIM_SIGTRAP); 1599*66e63ce3Schristos return 0; 1600*66e63ce3Schristos } 1601*66e63ce3Schristos 1602*66e63ce3Schristos /* trap */ 1603*66e63ce3Schristos int 1604*66e63ce3Schristos OP_10007E0 () 1605*66e63ce3Schristos { 1606*66e63ce3Schristos trace_input ("trap", OP_TRAP, 0); 1607*66e63ce3Schristos trace_output (OP_TRAP); 1608*66e63ce3Schristos 1609*66e63ce3Schristos /* Trap 31 is used for simulating OS I/O functions */ 1610*66e63ce3Schristos 1611*66e63ce3Schristos if (OP[0] == 31) 1612*66e63ce3Schristos { 1613*66e63ce3Schristos int save_errno = errno; 1614*66e63ce3Schristos errno = 0; 1615*66e63ce3Schristos 1616*66e63ce3Schristos /* Registers passed to trap 0 */ 1617*66e63ce3Schristos 1618*66e63ce3Schristos #define FUNC State.regs[6] /* function number, return value */ 1619*66e63ce3Schristos #define PARM1 State.regs[7] /* optional parm 1 */ 1620*66e63ce3Schristos #define PARM2 State.regs[8] /* optional parm 2 */ 1621*66e63ce3Schristos #define PARM3 State.regs[9] /* optional parm 3 */ 1622*66e63ce3Schristos 1623*66e63ce3Schristos /* Registers set by trap 0 */ 1624*66e63ce3Schristos 1625*66e63ce3Schristos #define RETVAL State.regs[10] /* return value */ 1626*66e63ce3Schristos #define RETERR State.regs[11] /* return error code */ 1627*66e63ce3Schristos 1628*66e63ce3Schristos /* Turn a pointer in a register into a pointer into real memory. */ 1629*66e63ce3Schristos 1630*66e63ce3Schristos #define MEMPTR(x) (map (x)) 1631*66e63ce3Schristos 1632*66e63ce3Schristos RETERR = 0; 1633*66e63ce3Schristos 1634*66e63ce3Schristos switch (FUNC) 1635*66e63ce3Schristos { 1636*66e63ce3Schristos 1637*66e63ce3Schristos #ifdef HAVE_FORK 1638*66e63ce3Schristos #ifdef TARGET_SYS_fork 1639*66e63ce3Schristos case TARGET_SYS_fork: 1640*66e63ce3Schristos RETVAL = fork (); 1641*66e63ce3Schristos RETERR = errno; 1642*66e63ce3Schristos break; 1643*66e63ce3Schristos #endif 1644*66e63ce3Schristos #endif 1645*66e63ce3Schristos 1646*66e63ce3Schristos #ifdef HAVE_EXECVE 1647*66e63ce3Schristos #ifdef TARGET_SYS_execv 1648*66e63ce3Schristos case TARGET_SYS_execve: 1649*66e63ce3Schristos { 1650*66e63ce3Schristos char *path = fetch_str (simulator, PARM1); 1651*66e63ce3Schristos char **argv = fetch_argv (simulator, PARM2); 1652*66e63ce3Schristos char **envp = fetch_argv (simulator, PARM3); 1653*66e63ce3Schristos RETVAL = execve (path, argv, envp); 1654*66e63ce3Schristos free (path); 1655*66e63ce3Schristos freeargv (argv); 1656*66e63ce3Schristos freeargv (envp); 1657*66e63ce3Schristos RETERR = errno; 1658*66e63ce3Schristos break; 1659*66e63ce3Schristos } 1660*66e63ce3Schristos #endif 1661*66e63ce3Schristos #endif 1662*66e63ce3Schristos 1663*66e63ce3Schristos #if HAVE_EXECV 1664*66e63ce3Schristos #ifdef TARGET_SYS_execv 1665*66e63ce3Schristos case TARGET_SYS_execv: 1666*66e63ce3Schristos { 1667*66e63ce3Schristos char *path = fetch_str (simulator, PARM1); 1668*66e63ce3Schristos char **argv = fetch_argv (simulator, PARM2); 1669*66e63ce3Schristos RETVAL = execv (path, argv); 1670*66e63ce3Schristos free (path); 1671*66e63ce3Schristos freeargv (argv); 1672*66e63ce3Schristos RETERR = errno; 1673*66e63ce3Schristos break; 1674*66e63ce3Schristos } 1675*66e63ce3Schristos #endif 1676*66e63ce3Schristos #endif 1677*66e63ce3Schristos 1678*66e63ce3Schristos #if 0 1679*66e63ce3Schristos #ifdef TARGET_SYS_pipe 1680*66e63ce3Schristos case TARGET_SYS_pipe: 1681*66e63ce3Schristos { 1682*66e63ce3Schristos reg_t buf; 1683*66e63ce3Schristos int host_fd[2]; 1684*66e63ce3Schristos 1685*66e63ce3Schristos buf = PARM1; 1686*66e63ce3Schristos RETVAL = pipe (host_fd); 1687*66e63ce3Schristos SW (buf, host_fd[0]); 1688*66e63ce3Schristos buf += sizeof(uint16); 1689*66e63ce3Schristos SW (buf, host_fd[1]); 1690*66e63ce3Schristos RETERR = errno; 1691*66e63ce3Schristos } 1692*66e63ce3Schristos break; 1693*66e63ce3Schristos #endif 1694*66e63ce3Schristos #endif 1695*66e63ce3Schristos 1696*66e63ce3Schristos #if 0 1697*66e63ce3Schristos #ifdef TARGET_SYS_wait 1698*66e63ce3Schristos case TARGET_SYS_wait: 1699*66e63ce3Schristos { 1700*66e63ce3Schristos int status; 1701*66e63ce3Schristos 1702*66e63ce3Schristos RETVAL = wait (&status); 1703*66e63ce3Schristos SW (PARM1, status); 1704*66e63ce3Schristos RETERR = errno; 1705*66e63ce3Schristos } 1706*66e63ce3Schristos break; 1707*66e63ce3Schristos #endif 1708*66e63ce3Schristos #endif 1709*66e63ce3Schristos 1710*66e63ce3Schristos #ifdef TARGET_SYS_read 1711*66e63ce3Schristos case TARGET_SYS_read: 1712*66e63ce3Schristos { 1713*66e63ce3Schristos char *buf = zalloc (PARM3); 1714*66e63ce3Schristos RETVAL = sim_io_read (simulator, PARM1, buf, PARM3); 1715*66e63ce3Schristos sim_write (simulator, PARM2, buf, PARM3); 1716*66e63ce3Schristos free (buf); 1717*66e63ce3Schristos if ((int) RETVAL < 0) 1718*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1719*66e63ce3Schristos break; 1720*66e63ce3Schristos } 1721*66e63ce3Schristos #endif 1722*66e63ce3Schristos 1723*66e63ce3Schristos #ifdef TARGET_SYS_write 1724*66e63ce3Schristos case TARGET_SYS_write: 1725*66e63ce3Schristos { 1726*66e63ce3Schristos char *buf = zalloc (PARM3); 1727*66e63ce3Schristos sim_read (simulator, PARM2, buf, PARM3); 1728*66e63ce3Schristos if (PARM1 == 1) 1729*66e63ce3Schristos RETVAL = sim_io_write_stdout (simulator, buf, PARM3); 1730*66e63ce3Schristos else 1731*66e63ce3Schristos RETVAL = sim_io_write (simulator, PARM1, buf, PARM3); 1732*66e63ce3Schristos free (buf); 1733*66e63ce3Schristos if ((int) RETVAL < 0) 1734*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1735*66e63ce3Schristos break; 1736*66e63ce3Schristos } 1737*66e63ce3Schristos #endif 1738*66e63ce3Schristos 1739*66e63ce3Schristos #ifdef TARGET_SYS_lseek 1740*66e63ce3Schristos case TARGET_SYS_lseek: 1741*66e63ce3Schristos RETVAL = sim_io_lseek (simulator, PARM1, PARM2, PARM3); 1742*66e63ce3Schristos if ((int) RETVAL < 0) 1743*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1744*66e63ce3Schristos break; 1745*66e63ce3Schristos #endif 1746*66e63ce3Schristos 1747*66e63ce3Schristos #ifdef TARGET_SYS_close 1748*66e63ce3Schristos case TARGET_SYS_close: 1749*66e63ce3Schristos RETVAL = sim_io_close (simulator, PARM1); 1750*66e63ce3Schristos if ((int) RETVAL < 0) 1751*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1752*66e63ce3Schristos break; 1753*66e63ce3Schristos #endif 1754*66e63ce3Schristos 1755*66e63ce3Schristos #ifdef TARGET_SYS_open 1756*66e63ce3Schristos case TARGET_SYS_open: 1757*66e63ce3Schristos { 1758*66e63ce3Schristos char *buf = fetch_str (simulator, PARM1); 1759*66e63ce3Schristos RETVAL = sim_io_open (simulator, buf, PARM2); 1760*66e63ce3Schristos free (buf); 1761*66e63ce3Schristos if ((int) RETVAL < 0) 1762*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1763*66e63ce3Schristos break; 1764*66e63ce3Schristos } 1765*66e63ce3Schristos #endif 1766*66e63ce3Schristos 1767*66e63ce3Schristos #ifdef TARGET_SYS_exit 1768*66e63ce3Schristos case TARGET_SYS_exit: 1769*66e63ce3Schristos if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0) 1770*66e63ce3Schristos /* get signal encoded by kill */ 1771*66e63ce3Schristos sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, 1772*66e63ce3Schristos sim_signalled, PARM1 & 0xffff); 1773*66e63ce3Schristos else if (PARM1 == 0xdead) 1774*66e63ce3Schristos /* old libraries */ 1775*66e63ce3Schristos sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, 1776*66e63ce3Schristos sim_stopped, SIM_SIGABRT); 1777*66e63ce3Schristos else 1778*66e63ce3Schristos /* PARM1 has exit status */ 1779*66e63ce3Schristos sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, 1780*66e63ce3Schristos sim_exited, PARM1); 1781*66e63ce3Schristos break; 1782*66e63ce3Schristos #endif 1783*66e63ce3Schristos 1784*66e63ce3Schristos #ifdef TARGET_SYS_stat 1785*66e63ce3Schristos case TARGET_SYS_stat: /* added at hmsi */ 1786*66e63ce3Schristos /* stat system call */ 1787*66e63ce3Schristos { 1788*66e63ce3Schristos struct stat host_stat; 1789*66e63ce3Schristos reg_t buf; 1790*66e63ce3Schristos char *path = fetch_str (simulator, PARM1); 1791*66e63ce3Schristos 1792*66e63ce3Schristos RETVAL = sim_io_stat (simulator, path, &host_stat); 1793*66e63ce3Schristos 1794*66e63ce3Schristos free (path); 1795*66e63ce3Schristos buf = PARM2; 1796*66e63ce3Schristos 1797*66e63ce3Schristos /* Just wild-assed guesses. */ 1798*66e63ce3Schristos store_mem (buf, 2, host_stat.st_dev); 1799*66e63ce3Schristos store_mem (buf + 2, 2, host_stat.st_ino); 1800*66e63ce3Schristos store_mem (buf + 4, 4, host_stat.st_mode); 1801*66e63ce3Schristos store_mem (buf + 8, 2, host_stat.st_nlink); 1802*66e63ce3Schristos store_mem (buf + 10, 2, host_stat.st_uid); 1803*66e63ce3Schristos store_mem (buf + 12, 2, host_stat.st_gid); 1804*66e63ce3Schristos store_mem (buf + 14, 2, host_stat.st_rdev); 1805*66e63ce3Schristos store_mem (buf + 16, 4, host_stat.st_size); 1806*66e63ce3Schristos store_mem (buf + 20, 4, host_stat.st_atime); 1807*66e63ce3Schristos store_mem (buf + 28, 4, host_stat.st_mtime); 1808*66e63ce3Schristos store_mem (buf + 36, 4, host_stat.st_ctime); 1809*66e63ce3Schristos 1810*66e63ce3Schristos if ((int) RETVAL < 0) 1811*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1812*66e63ce3Schristos } 1813*66e63ce3Schristos break; 1814*66e63ce3Schristos #endif 1815*66e63ce3Schristos 1816*66e63ce3Schristos #ifdef TARGET_SYS_fstat 1817*66e63ce3Schristos case TARGET_SYS_fstat: 1818*66e63ce3Schristos /* fstat system call */ 1819*66e63ce3Schristos { 1820*66e63ce3Schristos struct stat host_stat; 1821*66e63ce3Schristos reg_t buf; 1822*66e63ce3Schristos 1823*66e63ce3Schristos RETVAL = sim_io_fstat (simulator, PARM1, &host_stat); 1824*66e63ce3Schristos 1825*66e63ce3Schristos buf = PARM2; 1826*66e63ce3Schristos 1827*66e63ce3Schristos /* Just wild-assed guesses. */ 1828*66e63ce3Schristos store_mem (buf, 2, host_stat.st_dev); 1829*66e63ce3Schristos store_mem (buf + 2, 2, host_stat.st_ino); 1830*66e63ce3Schristos store_mem (buf + 4, 4, host_stat.st_mode); 1831*66e63ce3Schristos store_mem (buf + 8, 2, host_stat.st_nlink); 1832*66e63ce3Schristos store_mem (buf + 10, 2, host_stat.st_uid); 1833*66e63ce3Schristos store_mem (buf + 12, 2, host_stat.st_gid); 1834*66e63ce3Schristos store_mem (buf + 14, 2, host_stat.st_rdev); 1835*66e63ce3Schristos store_mem (buf + 16, 4, host_stat.st_size); 1836*66e63ce3Schristos store_mem (buf + 20, 4, host_stat.st_atime); 1837*66e63ce3Schristos store_mem (buf + 28, 4, host_stat.st_mtime); 1838*66e63ce3Schristos store_mem (buf + 36, 4, host_stat.st_ctime); 1839*66e63ce3Schristos 1840*66e63ce3Schristos if ((int) RETVAL < 0) 1841*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1842*66e63ce3Schristos } 1843*66e63ce3Schristos break; 1844*66e63ce3Schristos #endif 1845*66e63ce3Schristos 1846*66e63ce3Schristos #ifdef TARGET_SYS_rename 1847*66e63ce3Schristos case TARGET_SYS_rename: 1848*66e63ce3Schristos { 1849*66e63ce3Schristos char *oldpath = fetch_str (simulator, PARM1); 1850*66e63ce3Schristos char *newpath = fetch_str (simulator, PARM2); 1851*66e63ce3Schristos RETVAL = sim_io_rename (simulator, oldpath, newpath); 1852*66e63ce3Schristos free (oldpath); 1853*66e63ce3Schristos free (newpath); 1854*66e63ce3Schristos if ((int) RETVAL < 0) 1855*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1856*66e63ce3Schristos } 1857*66e63ce3Schristos break; 1858*66e63ce3Schristos #endif 1859*66e63ce3Schristos 1860*66e63ce3Schristos #ifdef TARGET_SYS_unlink 1861*66e63ce3Schristos case TARGET_SYS_unlink: 1862*66e63ce3Schristos { 1863*66e63ce3Schristos char *path = fetch_str (simulator, PARM1); 1864*66e63ce3Schristos RETVAL = sim_io_unlink (simulator, path); 1865*66e63ce3Schristos free (path); 1866*66e63ce3Schristos if ((int) RETVAL < 0) 1867*66e63ce3Schristos RETERR = sim_io_get_errno (simulator); 1868*66e63ce3Schristos } 1869*66e63ce3Schristos break; 1870*66e63ce3Schristos #endif 1871*66e63ce3Schristos 1872*66e63ce3Schristos #ifdef HAVE_CHOWN 1873*66e63ce3Schristos #ifdef TARGET_SYS_chown 1874*66e63ce3Schristos case TARGET_SYS_chown: 1875*66e63ce3Schristos { 1876*66e63ce3Schristos char *path = fetch_str (simulator, PARM1); 1877*66e63ce3Schristos RETVAL = chown (path, PARM2, PARM3); 1878*66e63ce3Schristos free (path); 1879*66e63ce3Schristos RETERR = errno; 1880*66e63ce3Schristos } 1881*66e63ce3Schristos break; 1882*66e63ce3Schristos #endif 1883*66e63ce3Schristos #endif 1884*66e63ce3Schristos 1885*66e63ce3Schristos #if HAVE_CHMOD 1886*66e63ce3Schristos #ifdef TARGET_SYS_chmod 1887*66e63ce3Schristos case TARGET_SYS_chmod: 1888*66e63ce3Schristos { 1889*66e63ce3Schristos char *path = fetch_str (simulator, PARM1); 1890*66e63ce3Schristos RETVAL = chmod (path, PARM2); 1891*66e63ce3Schristos free (path); 1892*66e63ce3Schristos RETERR = errno; 1893*66e63ce3Schristos } 1894*66e63ce3Schristos break; 1895*66e63ce3Schristos #endif 1896*66e63ce3Schristos #endif 1897*66e63ce3Schristos 1898*66e63ce3Schristos #ifdef TARGET_SYS_time 1899*66e63ce3Schristos #if HAVE_TIME 1900*66e63ce3Schristos case TARGET_SYS_time: 1901*66e63ce3Schristos { 1902*66e63ce3Schristos time_t now; 1903*66e63ce3Schristos RETVAL = time (&now); 1904*66e63ce3Schristos store_mem (PARM1, 4, now); 1905*66e63ce3Schristos RETERR = errno; 1906*66e63ce3Schristos } 1907*66e63ce3Schristos break; 1908*66e63ce3Schristos #endif 1909*66e63ce3Schristos #endif 1910*66e63ce3Schristos 1911*66e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32) 1912*66e63ce3Schristos #ifdef TARGET_SYS_times 1913*66e63ce3Schristos case TARGET_SYS_times: 1914*66e63ce3Schristos { 1915*66e63ce3Schristos struct tms tms; 1916*66e63ce3Schristos RETVAL = times (&tms); 1917*66e63ce3Schristos store_mem (PARM1, 4, tms.tms_utime); 1918*66e63ce3Schristos store_mem (PARM1 + 4, 4, tms.tms_stime); 1919*66e63ce3Schristos store_mem (PARM1 + 8, 4, tms.tms_cutime); 1920*66e63ce3Schristos store_mem (PARM1 + 12, 4, tms.tms_cstime); 1921*66e63ce3Schristos reterr = errno; 1922*66e63ce3Schristos break; 1923*66e63ce3Schristos } 1924*66e63ce3Schristos #endif 1925*66e63ce3Schristos #endif 1926*66e63ce3Schristos 1927*66e63ce3Schristos #ifdef TARGET_SYS_gettimeofday 1928*66e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32) 1929*66e63ce3Schristos case TARGET_SYS_gettimeofday: 1930*66e63ce3Schristos { 1931*66e63ce3Schristos struct timeval t; 1932*66e63ce3Schristos struct timezone tz; 1933*66e63ce3Schristos RETVAL = gettimeofday (&t, &tz); 1934*66e63ce3Schristos store_mem (PARM1, 4, t.tv_sec); 1935*66e63ce3Schristos store_mem (PARM1 + 4, 4, t.tv_usec); 1936*66e63ce3Schristos store_mem (PARM2, 4, tz.tz_minuteswest); 1937*66e63ce3Schristos store_mem (PARM2 + 4, 4, tz.tz_dsttime); 1938*66e63ce3Schristos RETERR = errno; 1939*66e63ce3Schristos break; 1940*66e63ce3Schristos } 1941*66e63ce3Schristos #endif 1942*66e63ce3Schristos #endif 1943*66e63ce3Schristos 1944*66e63ce3Schristos #ifdef TARGET_SYS_utime 1945*66e63ce3Schristos #if HAVE_UTIME 1946*66e63ce3Schristos case TARGET_SYS_utime: 1947*66e63ce3Schristos { 1948*66e63ce3Schristos /* Cast the second argument to void *, to avoid type mismatch 1949*66e63ce3Schristos if a prototype is present. */ 1950*66e63ce3Schristos sim_io_error (simulator, "Utime not supported"); 1951*66e63ce3Schristos /* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */ 1952*66e63ce3Schristos } 1953*66e63ce3Schristos break; 1954*66e63ce3Schristos #endif 1955*66e63ce3Schristos #endif 1956*66e63ce3Schristos 1957*66e63ce3Schristos default: 1958*66e63ce3Schristos abort (); 1959*66e63ce3Schristos } 1960*66e63ce3Schristos errno = save_errno; 1961*66e63ce3Schristos 1962*66e63ce3Schristos return 4; 1963*66e63ce3Schristos } 1964*66e63ce3Schristos else 1965*66e63ce3Schristos { /* Trap 0 -> 30 */ 1966*66e63ce3Schristos EIPC = PC + 4; 1967*66e63ce3Schristos EIPSW = PSW; 1968*66e63ce3Schristos /* Mask out EICC */ 1969*66e63ce3Schristos ECR &= 0xffff0000; 1970*66e63ce3Schristos ECR |= 0x40 + OP[0]; 1971*66e63ce3Schristos /* Flag that we are now doing exception processing. */ 1972*66e63ce3Schristos PSW |= PSW_EP | PSW_ID; 1973*66e63ce3Schristos PC = (OP[0] < 0x10) ? 0x40 : 0x50; 1974*66e63ce3Schristos 1975*66e63ce3Schristos return 0; 1976*66e63ce3Schristos } 1977*66e63ce3Schristos } 1978*66e63ce3Schristos 1979*66e63ce3Schristos /* tst1 reg2, [reg1] */ 1980*66e63ce3Schristos int 1981*66e63ce3Schristos OP_E607E0 (void) 1982*66e63ce3Schristos { 1983*66e63ce3Schristos int temp; 1984*66e63ce3Schristos 1985*66e63ce3Schristos trace_input ("tst1", OP_BIT, 1); 1986*66e63ce3Schristos 1987*66e63ce3Schristos temp = load_mem (State.regs[ OP[0] ], 1); 1988*66e63ce3Schristos 1989*66e63ce3Schristos PSW &= ~PSW_Z; 1990*66e63ce3Schristos if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0) 1991*66e63ce3Schristos PSW |= PSW_Z; 1992*66e63ce3Schristos 1993*66e63ce3Schristos trace_output (OP_BIT); 1994*66e63ce3Schristos 1995*66e63ce3Schristos return 4; 1996*66e63ce3Schristos } 1997*66e63ce3Schristos 1998*66e63ce3Schristos /* mulu reg1, reg2, reg3 */ 1999*66e63ce3Schristos int 2000*66e63ce3Schristos OP_22207E0 (void) 2001*66e63ce3Schristos { 2002*66e63ce3Schristos trace_input ("mulu", OP_REG_REG_REG, 0); 2003*66e63ce3Schristos 2004*66e63ce3Schristos Multiply64 (0, State.regs[ OP[0] ]); 2005*66e63ce3Schristos 2006*66e63ce3Schristos trace_output (OP_REG_REG_REG); 2007*66e63ce3Schristos 2008*66e63ce3Schristos return 4; 2009*66e63ce3Schristos } 2010*66e63ce3Schristos 2011*66e63ce3Schristos #define BIT_CHANGE_OP( name, binop ) \ 2012*66e63ce3Schristos unsigned int bit; \ 2013*66e63ce3Schristos unsigned int temp; \ 2014*66e63ce3Schristos \ 2015*66e63ce3Schristos trace_input (name, OP_BIT_CHANGE, 0); \ 2016*66e63ce3Schristos \ 2017*66e63ce3Schristos bit = 1 << (State.regs[ OP[1] ] & 0x7); \ 2018*66e63ce3Schristos temp = load_mem (State.regs[ OP[0] ], 1); \ 2019*66e63ce3Schristos \ 2020*66e63ce3Schristos PSW &= ~PSW_Z; \ 2021*66e63ce3Schristos if ((temp & bit) == 0) \ 2022*66e63ce3Schristos PSW |= PSW_Z; \ 2023*66e63ce3Schristos temp binop bit; \ 2024*66e63ce3Schristos \ 2025*66e63ce3Schristos store_mem (State.regs[ OP[0] ], 1, temp); \ 2026*66e63ce3Schristos \ 2027*66e63ce3Schristos trace_output (OP_BIT_CHANGE); \ 2028*66e63ce3Schristos \ 2029*66e63ce3Schristos return 4; 2030*66e63ce3Schristos 2031*66e63ce3Schristos /* clr1 reg2, [reg1] */ 2032*66e63ce3Schristos int 2033*66e63ce3Schristos OP_E407E0 (void) 2034*66e63ce3Schristos { 2035*66e63ce3Schristos BIT_CHANGE_OP ("clr1", &= ~ ); 2036*66e63ce3Schristos } 2037*66e63ce3Schristos 2038*66e63ce3Schristos /* not1 reg2, [reg1] */ 2039*66e63ce3Schristos int 2040*66e63ce3Schristos OP_E207E0 (void) 2041*66e63ce3Schristos { 2042*66e63ce3Schristos BIT_CHANGE_OP ("not1", ^= ); 2043*66e63ce3Schristos } 2044*66e63ce3Schristos 2045*66e63ce3Schristos /* set1 */ 2046*66e63ce3Schristos int 2047*66e63ce3Schristos OP_E007E0 (void) 2048*66e63ce3Schristos { 2049*66e63ce3Schristos BIT_CHANGE_OP ("set1", |= ); 2050*66e63ce3Schristos } 2051*66e63ce3Schristos 2052*66e63ce3Schristos /* sasf */ 2053*66e63ce3Schristos int 2054*66e63ce3Schristos OP_20007E0 (void) 2055*66e63ce3Schristos { 2056*66e63ce3Schristos trace_input ("sasf", OP_EX1, 0); 2057*66e63ce3Schristos 2058*66e63ce3Schristos State.regs[ OP[1] ] = (State.regs[ OP[1] ] << 1) | condition_met (OP[0]); 2059*66e63ce3Schristos 2060*66e63ce3Schristos trace_output (OP_EX1); 2061*66e63ce3Schristos 2062*66e63ce3Schristos return 4; 2063*66e63ce3Schristos } 2064*66e63ce3Schristos 2065*66e63ce3Schristos /* This function is courtesy of Sugimoto at NEC, via Seow Tan 2066*66e63ce3Schristos (Soew_Tan@el.nec.com) */ 2067*66e63ce3Schristos void 2068*66e63ce3Schristos divun 2069*66e63ce3Schristos ( 2070*66e63ce3Schristos unsigned int N, 2071*66e63ce3Schristos unsigned long int als, 2072*66e63ce3Schristos unsigned long int sfi, 2073*66e63ce3Schristos unsigned32 /*unsigned long int*/ * quotient_ptr, 2074*66e63ce3Schristos unsigned32 /*unsigned long int*/ * remainder_ptr, 2075*66e63ce3Schristos int * overflow_ptr 2076*66e63ce3Schristos ) 2077*66e63ce3Schristos { 2078*66e63ce3Schristos unsigned long ald = sfi >> (N - 1); 2079*66e63ce3Schristos unsigned long alo = als; 2080*66e63ce3Schristos unsigned int Q = 1; 2081*66e63ce3Schristos unsigned int C; 2082*66e63ce3Schristos unsigned int S = 0; 2083*66e63ce3Schristos unsigned int i; 2084*66e63ce3Schristos unsigned int R1 = 1; 2085*66e63ce3Schristos unsigned int DBZ = (als == 0) ? 1 : 0; 2086*66e63ce3Schristos unsigned long alt = Q ? ~als : als; 2087*66e63ce3Schristos 2088*66e63ce3Schristos /* 1st Loop */ 2089*66e63ce3Schristos alo = ald + alt + Q; 2090*66e63ce3Schristos C = (((alt >> 31) & (ald >> 31)) 2091*66e63ce3Schristos | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); 2092*66e63ce3Schristos C = C ^ Q; 2093*66e63ce3Schristos Q = ~(C ^ S) & 1; 2094*66e63ce3Schristos R1 = (alo == 0) ? 0 : (R1 & Q); 2095*66e63ce3Schristos if ((S ^ (alo>>31)) && !C) 2096*66e63ce3Schristos { 2097*66e63ce3Schristos DBZ = 1; 2098*66e63ce3Schristos } 2099*66e63ce3Schristos S = alo >> 31; 2100*66e63ce3Schristos sfi = (sfi << (32-N+1)) | Q; 2101*66e63ce3Schristos ald = (alo << 1) | (sfi >> 31); 2102*66e63ce3Schristos 2103*66e63ce3Schristos /* 2nd - N-1th Loop */ 2104*66e63ce3Schristos for (i = 2; i < N; i++) 2105*66e63ce3Schristos { 2106*66e63ce3Schristos alt = Q ? ~als : als; 2107*66e63ce3Schristos alo = ald + alt + Q; 2108*66e63ce3Schristos C = (((alt >> 31) & (ald >> 31)) 2109*66e63ce3Schristos | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); 2110*66e63ce3Schristos C = C ^ Q; 2111*66e63ce3Schristos Q = ~(C ^ S) & 1; 2112*66e63ce3Schristos R1 = (alo == 0) ? 0 : (R1 & Q); 2113*66e63ce3Schristos if ((S ^ (alo>>31)) && !C && !DBZ) 2114*66e63ce3Schristos { 2115*66e63ce3Schristos DBZ = 1; 2116*66e63ce3Schristos } 2117*66e63ce3Schristos S = alo >> 31; 2118*66e63ce3Schristos sfi = (sfi << 1) | Q; 2119*66e63ce3Schristos ald = (alo << 1) | (sfi >> 31); 2120*66e63ce3Schristos } 2121*66e63ce3Schristos 2122*66e63ce3Schristos /* Nth Loop */ 2123*66e63ce3Schristos alt = Q ? ~als : als; 2124*66e63ce3Schristos alo = ald + alt + Q; 2125*66e63ce3Schristos C = (((alt >> 31) & (ald >> 31)) 2126*66e63ce3Schristos | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); 2127*66e63ce3Schristos C = C ^ Q; 2128*66e63ce3Schristos Q = ~(C ^ S) & 1; 2129*66e63ce3Schristos R1 = (alo == 0) ? 0 : (R1 & Q); 2130*66e63ce3Schristos if ((S ^ (alo>>31)) && !C) 2131*66e63ce3Schristos { 2132*66e63ce3Schristos DBZ = 1; 2133*66e63ce3Schristos } 2134*66e63ce3Schristos 2135*66e63ce3Schristos * quotient_ptr = (sfi << 1) | Q; 2136*66e63ce3Schristos * remainder_ptr = Q ? alo : (alo + als); 2137*66e63ce3Schristos * overflow_ptr = DBZ | R1; 2138*66e63ce3Schristos } 2139*66e63ce3Schristos 2140*66e63ce3Schristos /* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */ 2141*66e63ce3Schristos void 2142*66e63ce3Schristos divn 2143*66e63ce3Schristos ( 2144*66e63ce3Schristos unsigned int N, 2145*66e63ce3Schristos unsigned long int als, 2146*66e63ce3Schristos unsigned long int sfi, 2147*66e63ce3Schristos signed32 /*signed long int*/ * quotient_ptr, 2148*66e63ce3Schristos signed32 /*signed long int*/ * remainder_ptr, 2149*66e63ce3Schristos int * overflow_ptr 2150*66e63ce3Schristos ) 2151*66e63ce3Schristos { 2152*66e63ce3Schristos unsigned long ald = (signed long) sfi >> (N - 1); 2153*66e63ce3Schristos unsigned long alo = als; 2154*66e63ce3Schristos unsigned int SS = als >> 31; 2155*66e63ce3Schristos unsigned int SD = sfi >> 31; 2156*66e63ce3Schristos unsigned int R1 = 1; 2157*66e63ce3Schristos unsigned int OV; 2158*66e63ce3Schristos unsigned int DBZ = als == 0 ? 1 : 0; 2159*66e63ce3Schristos unsigned int Q = ~(SS ^ SD) & 1; 2160*66e63ce3Schristos unsigned int C; 2161*66e63ce3Schristos unsigned int S; 2162*66e63ce3Schristos unsigned int i; 2163*66e63ce3Schristos unsigned long alt = Q ? ~als : als; 2164*66e63ce3Schristos 2165*66e63ce3Schristos 2166*66e63ce3Schristos /* 1st Loop */ 2167*66e63ce3Schristos 2168*66e63ce3Schristos alo = ald + alt + Q; 2169*66e63ce3Schristos C = (((alt >> 31) & (ald >> 31)) 2170*66e63ce3Schristos | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); 2171*66e63ce3Schristos Q = C ^ SS; 2172*66e63ce3Schristos R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); 2173*66e63ce3Schristos S = alo >> 31; 2174*66e63ce3Schristos sfi = (sfi << (32-N+1)) | Q; 2175*66e63ce3Schristos ald = (alo << 1) | (sfi >> 31); 2176*66e63ce3Schristos if ((alo >> 31) ^ (ald >> 31)) 2177*66e63ce3Schristos { 2178*66e63ce3Schristos DBZ = 1; 2179*66e63ce3Schristos } 2180*66e63ce3Schristos 2181*66e63ce3Schristos /* 2nd - N-1th Loop */ 2182*66e63ce3Schristos 2183*66e63ce3Schristos for (i = 2; i < N; i++) 2184*66e63ce3Schristos { 2185*66e63ce3Schristos alt = Q ? ~als : als; 2186*66e63ce3Schristos alo = ald + alt + Q; 2187*66e63ce3Schristos C = (((alt >> 31) & (ald >> 31)) 2188*66e63ce3Schristos | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); 2189*66e63ce3Schristos Q = C ^ SS; 2190*66e63ce3Schristos R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); 2191*66e63ce3Schristos S = alo >> 31; 2192*66e63ce3Schristos sfi = (sfi << 1) | Q; 2193*66e63ce3Schristos ald = (alo << 1) | (sfi >> 31); 2194*66e63ce3Schristos if ((alo >> 31) ^ (ald >> 31)) 2195*66e63ce3Schristos { 2196*66e63ce3Schristos DBZ = 1; 2197*66e63ce3Schristos } 2198*66e63ce3Schristos } 2199*66e63ce3Schristos 2200*66e63ce3Schristos /* Nth Loop */ 2201*66e63ce3Schristos alt = Q ? ~als : als; 2202*66e63ce3Schristos alo = ald + alt + Q; 2203*66e63ce3Schristos C = (((alt >> 31) & (ald >> 31)) 2204*66e63ce3Schristos | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); 2205*66e63ce3Schristos Q = C ^ SS; 2206*66e63ce3Schristos R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); 2207*66e63ce3Schristos sfi = (sfi << (32-N+1)); 2208*66e63ce3Schristos ald = alo; 2209*66e63ce3Schristos 2210*66e63ce3Schristos /* End */ 2211*66e63ce3Schristos if (alo != 0) 2212*66e63ce3Schristos { 2213*66e63ce3Schristos alt = Q ? ~als : als; 2214*66e63ce3Schristos alo = ald + alt + Q; 2215*66e63ce3Schristos } 2216*66e63ce3Schristos R1 = R1 & ((~alo >> 31) ^ SD); 2217*66e63ce3Schristos if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald; 2218*66e63ce3Schristos if (N != 32) 2219*66e63ce3Schristos ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q; 2220*66e63ce3Schristos else 2221*66e63ce3Schristos ald = sfi = sfi | Q; 2222*66e63ce3Schristos 2223*66e63ce3Schristos OV = DBZ | ((alo == 0) ? 0 : R1); 2224*66e63ce3Schristos 2225*66e63ce3Schristos * remainder_ptr = alo; 2226*66e63ce3Schristos 2227*66e63ce3Schristos /* Adj */ 2228*66e63ce3Schristos if (((alo != 0) && ((SS ^ SD) ^ R1)) 2229*66e63ce3Schristos || ((alo == 0) && (SS ^ R1))) 2230*66e63ce3Schristos alo = ald + 1; 2231*66e63ce3Schristos else 2232*66e63ce3Schristos alo = ald; 2233*66e63ce3Schristos 2234*66e63ce3Schristos OV = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31)); 2235*66e63ce3Schristos 2236*66e63ce3Schristos * quotient_ptr = alo; 2237*66e63ce3Schristos * overflow_ptr = OV; 2238*66e63ce3Schristos } 2239*66e63ce3Schristos 2240*66e63ce3Schristos /* sdivun imm5, reg1, reg2, reg3 */ 2241*66e63ce3Schristos int 2242*66e63ce3Schristos OP_1C207E0 (void) 2243*66e63ce3Schristos { 2244*66e63ce3Schristos unsigned32 /*unsigned long int*/ quotient; 2245*66e63ce3Schristos unsigned32 /*unsigned long int*/ remainder; 2246*66e63ce3Schristos unsigned long int divide_by; 2247*66e63ce3Schristos unsigned long int divide_this; 2248*66e63ce3Schristos int overflow = 0; 2249*66e63ce3Schristos unsigned int imm5; 2250*66e63ce3Schristos 2251*66e63ce3Schristos trace_input ("sdivun", OP_IMM_REG_REG_REG, 0); 2252*66e63ce3Schristos 2253*66e63ce3Schristos imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); 2254*66e63ce3Schristos 2255*66e63ce3Schristos divide_by = State.regs[ OP[0] ]; 2256*66e63ce3Schristos divide_this = State.regs[ OP[1] ] << imm5; 2257*66e63ce3Schristos 2258*66e63ce3Schristos divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); 2259*66e63ce3Schristos 2260*66e63ce3Schristos State.regs[ OP[1] ] = quotient; 2261*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder; 2262*66e63ce3Schristos 2263*66e63ce3Schristos /* Set condition codes. */ 2264*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2265*66e63ce3Schristos 2266*66e63ce3Schristos if (overflow) PSW |= PSW_OV; 2267*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2268*66e63ce3Schristos if (quotient & 0x80000000) PSW |= PSW_S; 2269*66e63ce3Schristos 2270*66e63ce3Schristos trace_output (OP_IMM_REG_REG_REG); 2271*66e63ce3Schristos 2272*66e63ce3Schristos return 4; 2273*66e63ce3Schristos } 2274*66e63ce3Schristos 2275*66e63ce3Schristos /* sdivn imm5, reg1, reg2, reg3 */ 2276*66e63ce3Schristos int 2277*66e63ce3Schristos OP_1C007E0 (void) 2278*66e63ce3Schristos { 2279*66e63ce3Schristos signed32 /*signed long int*/ quotient; 2280*66e63ce3Schristos signed32 /*signed long int*/ remainder; 2281*66e63ce3Schristos signed long int divide_by; 2282*66e63ce3Schristos signed long int divide_this; 2283*66e63ce3Schristos int overflow = 0; 2284*66e63ce3Schristos unsigned int imm5; 2285*66e63ce3Schristos 2286*66e63ce3Schristos trace_input ("sdivn", OP_IMM_REG_REG_REG, 0); 2287*66e63ce3Schristos 2288*66e63ce3Schristos imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); 2289*66e63ce3Schristos 2290*66e63ce3Schristos divide_by = (signed32) State.regs[ OP[0] ]; 2291*66e63ce3Schristos divide_this = (signed32) (State.regs[ OP[1] ] << imm5); 2292*66e63ce3Schristos 2293*66e63ce3Schristos divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); 2294*66e63ce3Schristos 2295*66e63ce3Schristos State.regs[ OP[1] ] = quotient; 2296*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder; 2297*66e63ce3Schristos 2298*66e63ce3Schristos /* Set condition codes. */ 2299*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2300*66e63ce3Schristos 2301*66e63ce3Schristos if (overflow) PSW |= PSW_OV; 2302*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2303*66e63ce3Schristos if (quotient < 0) PSW |= PSW_S; 2304*66e63ce3Schristos 2305*66e63ce3Schristos trace_output (OP_IMM_REG_REG_REG); 2306*66e63ce3Schristos 2307*66e63ce3Schristos return 4; 2308*66e63ce3Schristos } 2309*66e63ce3Schristos 2310*66e63ce3Schristos /* sdivhun imm5, reg1, reg2, reg3 */ 2311*66e63ce3Schristos int 2312*66e63ce3Schristos OP_18207E0 (void) 2313*66e63ce3Schristos { 2314*66e63ce3Schristos unsigned32 /*unsigned long int*/ quotient; 2315*66e63ce3Schristos unsigned32 /*unsigned long int*/ remainder; 2316*66e63ce3Schristos unsigned long int divide_by; 2317*66e63ce3Schristos unsigned long int divide_this; 2318*66e63ce3Schristos int overflow = 0; 2319*66e63ce3Schristos unsigned int imm5; 2320*66e63ce3Schristos 2321*66e63ce3Schristos trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0); 2322*66e63ce3Schristos 2323*66e63ce3Schristos imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); 2324*66e63ce3Schristos 2325*66e63ce3Schristos divide_by = State.regs[ OP[0] ] & 0xffff; 2326*66e63ce3Schristos divide_this = State.regs[ OP[1] ] << imm5; 2327*66e63ce3Schristos 2328*66e63ce3Schristos divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); 2329*66e63ce3Schristos 2330*66e63ce3Schristos State.regs[ OP[1] ] = quotient; 2331*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder; 2332*66e63ce3Schristos 2333*66e63ce3Schristos /* Set condition codes. */ 2334*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2335*66e63ce3Schristos 2336*66e63ce3Schristos if (overflow) PSW |= PSW_OV; 2337*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2338*66e63ce3Schristos if (quotient & 0x80000000) PSW |= PSW_S; 2339*66e63ce3Schristos 2340*66e63ce3Schristos trace_output (OP_IMM_REG_REG_REG); 2341*66e63ce3Schristos 2342*66e63ce3Schristos return 4; 2343*66e63ce3Schristos } 2344*66e63ce3Schristos 2345*66e63ce3Schristos /* sdivhn imm5, reg1, reg2, reg3 */ 2346*66e63ce3Schristos int 2347*66e63ce3Schristos OP_18007E0 (void) 2348*66e63ce3Schristos { 2349*66e63ce3Schristos signed32 /*signed long int*/ quotient; 2350*66e63ce3Schristos signed32 /*signed long int*/ remainder; 2351*66e63ce3Schristos signed long int divide_by; 2352*66e63ce3Schristos signed long int divide_this; 2353*66e63ce3Schristos int overflow = 0; 2354*66e63ce3Schristos unsigned int imm5; 2355*66e63ce3Schristos 2356*66e63ce3Schristos trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0); 2357*66e63ce3Schristos 2358*66e63ce3Schristos imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); 2359*66e63ce3Schristos 2360*66e63ce3Schristos divide_by = EXTEND16 (State.regs[ OP[0] ]); 2361*66e63ce3Schristos divide_this = (signed32) (State.regs[ OP[1] ] << imm5); 2362*66e63ce3Schristos 2363*66e63ce3Schristos divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); 2364*66e63ce3Schristos 2365*66e63ce3Schristos State.regs[ OP[1] ] = quotient; 2366*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder; 2367*66e63ce3Schristos 2368*66e63ce3Schristos /* Set condition codes. */ 2369*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2370*66e63ce3Schristos 2371*66e63ce3Schristos if (overflow) PSW |= PSW_OV; 2372*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2373*66e63ce3Schristos if (quotient < 0) PSW |= PSW_S; 2374*66e63ce3Schristos 2375*66e63ce3Schristos trace_output (OP_IMM_REG_REG_REG); 2376*66e63ce3Schristos 2377*66e63ce3Schristos return 4; 2378*66e63ce3Schristos } 2379*66e63ce3Schristos 2380*66e63ce3Schristos /* divu reg1, reg2, reg3 */ 2381*66e63ce3Schristos int 2382*66e63ce3Schristos OP_2C207E0 (void) 2383*66e63ce3Schristos { 2384*66e63ce3Schristos unsigned long int quotient; 2385*66e63ce3Schristos unsigned long int remainder; 2386*66e63ce3Schristos unsigned long int divide_by; 2387*66e63ce3Schristos unsigned long int divide_this; 2388*66e63ce3Schristos int overflow = 0; 2389*66e63ce3Schristos 2390*66e63ce3Schristos trace_input ("divu", OP_REG_REG_REG, 0); 2391*66e63ce3Schristos 2392*66e63ce3Schristos /* Compute the result. */ 2393*66e63ce3Schristos 2394*66e63ce3Schristos divide_by = State.regs[ OP[0] ]; 2395*66e63ce3Schristos divide_this = State.regs[ OP[1] ]; 2396*66e63ce3Schristos 2397*66e63ce3Schristos if (divide_by == 0) 2398*66e63ce3Schristos { 2399*66e63ce3Schristos PSW |= PSW_OV; 2400*66e63ce3Schristos } 2401*66e63ce3Schristos else 2402*66e63ce3Schristos { 2403*66e63ce3Schristos State.regs[ OP[1] ] = quotient = divide_this / divide_by; 2404*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; 2405*66e63ce3Schristos 2406*66e63ce3Schristos /* Set condition codes. */ 2407*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2408*66e63ce3Schristos 2409*66e63ce3Schristos if (overflow) PSW |= PSW_OV; 2410*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2411*66e63ce3Schristos if (quotient & 0x80000000) PSW |= PSW_S; 2412*66e63ce3Schristos } 2413*66e63ce3Schristos 2414*66e63ce3Schristos trace_output (OP_REG_REG_REG); 2415*66e63ce3Schristos 2416*66e63ce3Schristos return 4; 2417*66e63ce3Schristos } 2418*66e63ce3Schristos 2419*66e63ce3Schristos /* div reg1, reg2, reg3 */ 2420*66e63ce3Schristos int 2421*66e63ce3Schristos OP_2C007E0 (void) 2422*66e63ce3Schristos { 2423*66e63ce3Schristos signed long int quotient; 2424*66e63ce3Schristos signed long int remainder; 2425*66e63ce3Schristos signed long int divide_by; 2426*66e63ce3Schristos signed long int divide_this; 2427*66e63ce3Schristos 2428*66e63ce3Schristos trace_input ("div", OP_REG_REG_REG, 0); 2429*66e63ce3Schristos 2430*66e63ce3Schristos /* Compute the result. */ 2431*66e63ce3Schristos 2432*66e63ce3Schristos divide_by = (signed32) State.regs[ OP[0] ]; 2433*66e63ce3Schristos divide_this = State.regs[ OP[1] ]; 2434*66e63ce3Schristos 2435*66e63ce3Schristos if (divide_by == 0) 2436*66e63ce3Schristos { 2437*66e63ce3Schristos PSW |= PSW_OV; 2438*66e63ce3Schristos } 2439*66e63ce3Schristos else if (divide_by == -1 && divide_this == (1L << 31)) 2440*66e63ce3Schristos { 2441*66e63ce3Schristos PSW &= ~PSW_Z; 2442*66e63ce3Schristos PSW |= PSW_OV | PSW_S; 2443*66e63ce3Schristos State.regs[ OP[1] ] = (1 << 31); 2444*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = 0; 2445*66e63ce3Schristos } 2446*66e63ce3Schristos else 2447*66e63ce3Schristos { 2448*66e63ce3Schristos divide_this = (signed32) divide_this; 2449*66e63ce3Schristos State.regs[ OP[1] ] = quotient = divide_this / divide_by; 2450*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; 2451*66e63ce3Schristos 2452*66e63ce3Schristos /* Set condition codes. */ 2453*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2454*66e63ce3Schristos 2455*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2456*66e63ce3Schristos if (quotient < 0) PSW |= PSW_S; 2457*66e63ce3Schristos } 2458*66e63ce3Schristos 2459*66e63ce3Schristos trace_output (OP_REG_REG_REG); 2460*66e63ce3Schristos 2461*66e63ce3Schristos return 4; 2462*66e63ce3Schristos } 2463*66e63ce3Schristos 2464*66e63ce3Schristos /* divhu reg1, reg2, reg3 */ 2465*66e63ce3Schristos int 2466*66e63ce3Schristos OP_28207E0 (void) 2467*66e63ce3Schristos { 2468*66e63ce3Schristos unsigned long int quotient; 2469*66e63ce3Schristos unsigned long int remainder; 2470*66e63ce3Schristos unsigned long int divide_by; 2471*66e63ce3Schristos unsigned long int divide_this; 2472*66e63ce3Schristos int overflow = 0; 2473*66e63ce3Schristos 2474*66e63ce3Schristos trace_input ("divhu", OP_REG_REG_REG, 0); 2475*66e63ce3Schristos 2476*66e63ce3Schristos /* Compute the result. */ 2477*66e63ce3Schristos 2478*66e63ce3Schristos divide_by = State.regs[ OP[0] ] & 0xffff; 2479*66e63ce3Schristos divide_this = State.regs[ OP[1] ]; 2480*66e63ce3Schristos 2481*66e63ce3Schristos if (divide_by == 0) 2482*66e63ce3Schristos { 2483*66e63ce3Schristos PSW |= PSW_OV; 2484*66e63ce3Schristos } 2485*66e63ce3Schristos else 2486*66e63ce3Schristos { 2487*66e63ce3Schristos State.regs[ OP[1] ] = quotient = divide_this / divide_by; 2488*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; 2489*66e63ce3Schristos 2490*66e63ce3Schristos /* Set condition codes. */ 2491*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2492*66e63ce3Schristos 2493*66e63ce3Schristos if (overflow) PSW |= PSW_OV; 2494*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2495*66e63ce3Schristos if (quotient & 0x80000000) PSW |= PSW_S; 2496*66e63ce3Schristos } 2497*66e63ce3Schristos 2498*66e63ce3Schristos trace_output (OP_REG_REG_REG); 2499*66e63ce3Schristos 2500*66e63ce3Schristos return 4; 2501*66e63ce3Schristos } 2502*66e63ce3Schristos 2503*66e63ce3Schristos /* divh reg1, reg2, reg3 */ 2504*66e63ce3Schristos int 2505*66e63ce3Schristos OP_28007E0 (void) 2506*66e63ce3Schristos { 2507*66e63ce3Schristos signed long int quotient; 2508*66e63ce3Schristos signed long int remainder; 2509*66e63ce3Schristos signed long int divide_by; 2510*66e63ce3Schristos signed long int divide_this; 2511*66e63ce3Schristos int overflow = 0; 2512*66e63ce3Schristos 2513*66e63ce3Schristos trace_input ("divh", OP_REG_REG_REG, 0); 2514*66e63ce3Schristos 2515*66e63ce3Schristos /* Compute the result. */ 2516*66e63ce3Schristos 2517*66e63ce3Schristos divide_by = EXTEND16 (State.regs[ OP[0] ]); 2518*66e63ce3Schristos divide_this = State.regs[ OP[1] ]; 2519*66e63ce3Schristos 2520*66e63ce3Schristos if (divide_by == 0) 2521*66e63ce3Schristos { 2522*66e63ce3Schristos PSW |= PSW_OV; 2523*66e63ce3Schristos } 2524*66e63ce3Schristos else if (divide_by == -1 && divide_this == (1L << 31)) 2525*66e63ce3Schristos { 2526*66e63ce3Schristos PSW &= ~PSW_Z; 2527*66e63ce3Schristos PSW |= PSW_OV | PSW_S; 2528*66e63ce3Schristos State.regs[ OP[1] ] = (1 << 31); 2529*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = 0; 2530*66e63ce3Schristos } 2531*66e63ce3Schristos else 2532*66e63ce3Schristos { 2533*66e63ce3Schristos divide_this = (signed32) divide_this; 2534*66e63ce3Schristos State.regs[ OP[1] ] = quotient = divide_this / divide_by; 2535*66e63ce3Schristos State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; 2536*66e63ce3Schristos 2537*66e63ce3Schristos /* Set condition codes. */ 2538*66e63ce3Schristos PSW &= ~(PSW_Z | PSW_S | PSW_OV); 2539*66e63ce3Schristos 2540*66e63ce3Schristos if (quotient == 0) PSW |= PSW_Z; 2541*66e63ce3Schristos if (quotient < 0) PSW |= PSW_S; 2542*66e63ce3Schristos } 2543*66e63ce3Schristos 2544*66e63ce3Schristos trace_output (OP_REG_REG_REG); 2545*66e63ce3Schristos 2546*66e63ce3Schristos return 4; 2547*66e63ce3Schristos } 2548*66e63ce3Schristos 2549*66e63ce3Schristos /* mulu imm9, reg2, reg3 */ 2550*66e63ce3Schristos int 2551*66e63ce3Schristos OP_24207E0 (void) 2552*66e63ce3Schristos { 2553*66e63ce3Schristos trace_input ("mulu", OP_IMM_REG_REG, 0); 2554*66e63ce3Schristos 2555*66e63ce3Schristos Multiply64 (0, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0)); 2556*66e63ce3Schristos 2557*66e63ce3Schristos trace_output (OP_IMM_REG_REG); 2558*66e63ce3Schristos 2559*66e63ce3Schristos return 4; 2560*66e63ce3Schristos } 2561*66e63ce3Schristos 2562*66e63ce3Schristos /* mul imm9, reg2, reg3 */ 2563*66e63ce3Schristos int 2564*66e63ce3Schristos OP_24007E0 (void) 2565*66e63ce3Schristos { 2566*66e63ce3Schristos trace_input ("mul", OP_IMM_REG_REG, 0); 2567*66e63ce3Schristos 2568*66e63ce3Schristos Multiply64 (1, SEXT9 ((OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0))); 2569*66e63ce3Schristos 2570*66e63ce3Schristos trace_output (OP_IMM_REG_REG); 2571*66e63ce3Schristos 2572*66e63ce3Schristos return 4; 2573*66e63ce3Schristos } 2574*66e63ce3Schristos 2575*66e63ce3Schristos /* ld.hu */ 2576*66e63ce3Schristos int 2577*66e63ce3Schristos OP_107E0 (void) 2578*66e63ce3Schristos { 2579*66e63ce3Schristos int adr; 2580*66e63ce3Schristos 2581*66e63ce3Schristos trace_input ("ld.hu", OP_LOAD32, 2); 2582*66e63ce3Schristos 2583*66e63ce3Schristos adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); 2584*66e63ce3Schristos adr &= ~0x1; 2585*66e63ce3Schristos 2586*66e63ce3Schristos State.regs[ OP[1] ] = load_mem (adr, 2); 2587*66e63ce3Schristos 2588*66e63ce3Schristos trace_output (OP_LOAD32); 2589*66e63ce3Schristos 2590*66e63ce3Schristos return 4; 2591*66e63ce3Schristos } 2592*66e63ce3Schristos 2593*66e63ce3Schristos 2594*66e63ce3Schristos /* ld.bu */ 2595*66e63ce3Schristos int 2596*66e63ce3Schristos OP_10780 (void) 2597*66e63ce3Schristos { 2598*66e63ce3Schristos int adr; 2599*66e63ce3Schristos 2600*66e63ce3Schristos trace_input ("ld.bu", OP_LOAD32, 1); 2601*66e63ce3Schristos 2602*66e63ce3Schristos adr = (State.regs[ OP[0] ] 2603*66e63ce3Schristos + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1))); 2604*66e63ce3Schristos 2605*66e63ce3Schristos State.regs[ OP[1] ] = load_mem (adr, 1); 2606*66e63ce3Schristos 2607*66e63ce3Schristos trace_output (OP_LOAD32); 2608*66e63ce3Schristos 2609*66e63ce3Schristos return 4; 2610*66e63ce3Schristos } 2611*66e63ce3Schristos 2612*66e63ce3Schristos /* prepare list12, imm5, imm32 */ 2613*66e63ce3Schristos int 2614*66e63ce3Schristos OP_1B0780 (void) 2615*66e63ce3Schristos { 2616*66e63ce3Schristos int i; 2617*66e63ce3Schristos 2618*66e63ce3Schristos trace_input ("prepare", OP_PUSHPOP1, 0); 2619*66e63ce3Schristos 2620*66e63ce3Schristos /* Store the registers with lower number registers being placed at higher addresses. */ 2621*66e63ce3Schristos for (i = 0; i < 12; i++) 2622*66e63ce3Schristos if ((OP[3] & (1 << type1_regs[ i ]))) 2623*66e63ce3Schristos { 2624*66e63ce3Schristos SP -= 4; 2625*66e63ce3Schristos store_mem (SP, 4, State.regs[ 20 + i ]); 2626*66e63ce3Schristos } 2627*66e63ce3Schristos 2628*66e63ce3Schristos SP -= (OP[3] & 0x3e) << 1; 2629*66e63ce3Schristos 2630*66e63ce3Schristos EP = load_mem (PC + 4, 4); 2631*66e63ce3Schristos 2632*66e63ce3Schristos trace_output (OP_PUSHPOP1); 2633*66e63ce3Schristos 2634*66e63ce3Schristos return 8; 2635*66e63ce3Schristos } 2636*66e63ce3Schristos 2637*66e63ce3Schristos /* prepare list12, imm5, imm16-32 */ 2638*66e63ce3Schristos int 2639*66e63ce3Schristos OP_130780 (void) 2640*66e63ce3Schristos { 2641*66e63ce3Schristos int i; 2642*66e63ce3Schristos 2643*66e63ce3Schristos trace_input ("prepare", OP_PUSHPOP1, 0); 2644*66e63ce3Schristos 2645*66e63ce3Schristos /* Store the registers with lower number registers being placed at higher addresses. */ 2646*66e63ce3Schristos for (i = 0; i < 12; i++) 2647*66e63ce3Schristos if ((OP[3] & (1 << type1_regs[ i ]))) 2648*66e63ce3Schristos { 2649*66e63ce3Schristos SP -= 4; 2650*66e63ce3Schristos store_mem (SP, 4, State.regs[ 20 + i ]); 2651*66e63ce3Schristos } 2652*66e63ce3Schristos 2653*66e63ce3Schristos SP -= (OP[3] & 0x3e) << 1; 2654*66e63ce3Schristos 2655*66e63ce3Schristos EP = load_mem (PC + 4, 2) << 16; 2656*66e63ce3Schristos 2657*66e63ce3Schristos trace_output (OP_PUSHPOP1); 2658*66e63ce3Schristos 2659*66e63ce3Schristos return 6; 2660*66e63ce3Schristos } 2661*66e63ce3Schristos 2662*66e63ce3Schristos /* prepare list12, imm5, imm16 */ 2663*66e63ce3Schristos int 2664*66e63ce3Schristos OP_B0780 (void) 2665*66e63ce3Schristos { 2666*66e63ce3Schristos int i; 2667*66e63ce3Schristos 2668*66e63ce3Schristos trace_input ("prepare", OP_PUSHPOP1, 0); 2669*66e63ce3Schristos 2670*66e63ce3Schristos /* Store the registers with lower number registers being placed at higher addresses. */ 2671*66e63ce3Schristos for (i = 0; i < 12; i++) 2672*66e63ce3Schristos if ((OP[3] & (1 << type1_regs[ i ]))) 2673*66e63ce3Schristos { 2674*66e63ce3Schristos SP -= 4; 2675*66e63ce3Schristos store_mem (SP, 4, State.regs[ 20 + i ]); 2676*66e63ce3Schristos } 2677*66e63ce3Schristos 2678*66e63ce3Schristos SP -= (OP[3] & 0x3e) << 1; 2679*66e63ce3Schristos 2680*66e63ce3Schristos EP = EXTEND16 (load_mem (PC + 4, 2)); 2681*66e63ce3Schristos 2682*66e63ce3Schristos trace_output (OP_PUSHPOP1); 2683*66e63ce3Schristos 2684*66e63ce3Schristos return 6; 2685*66e63ce3Schristos } 2686*66e63ce3Schristos 2687*66e63ce3Schristos /* prepare list12, imm5, sp */ 2688*66e63ce3Schristos int 2689*66e63ce3Schristos OP_30780 (void) 2690*66e63ce3Schristos { 2691*66e63ce3Schristos int i; 2692*66e63ce3Schristos 2693*66e63ce3Schristos trace_input ("prepare", OP_PUSHPOP1, 0); 2694*66e63ce3Schristos 2695*66e63ce3Schristos /* Store the registers with lower number registers being placed at higher addresses. */ 2696*66e63ce3Schristos for (i = 0; i < 12; i++) 2697*66e63ce3Schristos if ((OP[3] & (1 << type1_regs[ i ]))) 2698*66e63ce3Schristos { 2699*66e63ce3Schristos SP -= 4; 2700*66e63ce3Schristos store_mem (SP, 4, State.regs[ 20 + i ]); 2701*66e63ce3Schristos } 2702*66e63ce3Schristos 2703*66e63ce3Schristos SP -= (OP[3] & 0x3e) << 1; 2704*66e63ce3Schristos 2705*66e63ce3Schristos EP = SP; 2706*66e63ce3Schristos 2707*66e63ce3Schristos trace_output (OP_PUSHPOP1); 2708*66e63ce3Schristos 2709*66e63ce3Schristos return 4; 2710*66e63ce3Schristos } 2711*66e63ce3Schristos 2712*66e63ce3Schristos /* mul reg1, reg2, reg3 */ 2713*66e63ce3Schristos int 2714*66e63ce3Schristos OP_22007E0 (void) 2715*66e63ce3Schristos { 2716*66e63ce3Schristos trace_input ("mul", OP_REG_REG_REG, 0); 2717*66e63ce3Schristos 2718*66e63ce3Schristos Multiply64 (1, State.regs[ OP[0] ]); 2719*66e63ce3Schristos 2720*66e63ce3Schristos trace_output (OP_REG_REG_REG); 2721*66e63ce3Schristos 2722*66e63ce3Schristos return 4; 2723*66e63ce3Schristos } 2724*66e63ce3Schristos 2725*66e63ce3Schristos /* popmh list18 */ 2726*66e63ce3Schristos int 2727*66e63ce3Schristos OP_307F0 (void) 2728*66e63ce3Schristos { 2729*66e63ce3Schristos int i; 2730*66e63ce3Schristos 2731*66e63ce3Schristos trace_input ("popmh", OP_PUSHPOP2, 0); 2732*66e63ce3Schristos 2733*66e63ce3Schristos if (OP[3] & (1 << 19)) 2734*66e63ce3Schristos { 2735*66e63ce3Schristos if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) 2736*66e63ce3Schristos { 2737*66e63ce3Schristos FEPSW = load_mem ( SP & ~ 3, 4); 2738*66e63ce3Schristos FEPC = load_mem ((SP + 4) & ~ 3, 4); 2739*66e63ce3Schristos } 2740*66e63ce3Schristos else 2741*66e63ce3Schristos { 2742*66e63ce3Schristos EIPSW = load_mem ( SP & ~ 3, 4); 2743*66e63ce3Schristos EIPC = load_mem ((SP + 4) & ~ 3, 4); 2744*66e63ce3Schristos } 2745*66e63ce3Schristos 2746*66e63ce3Schristos SP += 8; 2747*66e63ce3Schristos } 2748*66e63ce3Schristos 2749*66e63ce3Schristos /* Load the registers with lower number registers being retrieved from higher addresses. */ 2750*66e63ce3Schristos for (i = 16; i--;) 2751*66e63ce3Schristos if ((OP[3] & (1 << type2_regs[ i ]))) 2752*66e63ce3Schristos { 2753*66e63ce3Schristos State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4); 2754*66e63ce3Schristos SP += 4; 2755*66e63ce3Schristos } 2756*66e63ce3Schristos 2757*66e63ce3Schristos trace_output (OP_PUSHPOP2); 2758*66e63ce3Schristos 2759*66e63ce3Schristos return 4; 2760*66e63ce3Schristos } 2761*66e63ce3Schristos 2762*66e63ce3Schristos /* popml lsit18 */ 2763*66e63ce3Schristos int 2764*66e63ce3Schristos OP_107F0 (void) 2765*66e63ce3Schristos { 2766*66e63ce3Schristos int i; 2767*66e63ce3Schristos 2768*66e63ce3Schristos trace_input ("popml", OP_PUSHPOP3, 0); 2769*66e63ce3Schristos 2770*66e63ce3Schristos if (OP[3] & (1 << 19)) 2771*66e63ce3Schristos { 2772*66e63ce3Schristos if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) 2773*66e63ce3Schristos { 2774*66e63ce3Schristos FEPSW = load_mem ( SP & ~ 3, 4); 2775*66e63ce3Schristos FEPC = load_mem ((SP + 4) & ~ 3, 4); 2776*66e63ce3Schristos } 2777*66e63ce3Schristos else 2778*66e63ce3Schristos { 2779*66e63ce3Schristos EIPSW = load_mem ( SP & ~ 3, 4); 2780*66e63ce3Schristos EIPC = load_mem ((SP + 4) & ~ 3, 4); 2781*66e63ce3Schristos } 2782*66e63ce3Schristos 2783*66e63ce3Schristos SP += 8; 2784*66e63ce3Schristos } 2785*66e63ce3Schristos 2786*66e63ce3Schristos if (OP[3] & (1 << 3)) 2787*66e63ce3Schristos { 2788*66e63ce3Schristos PSW = load_mem (SP & ~ 3, 4); 2789*66e63ce3Schristos SP += 4; 2790*66e63ce3Schristos } 2791*66e63ce3Schristos 2792*66e63ce3Schristos /* Load the registers with lower number registers being retrieved from higher addresses. */ 2793*66e63ce3Schristos for (i = 15; i--;) 2794*66e63ce3Schristos if ((OP[3] & (1 << type3_regs[ i ]))) 2795*66e63ce3Schristos { 2796*66e63ce3Schristos State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4); 2797*66e63ce3Schristos SP += 4; 2798*66e63ce3Schristos } 2799*66e63ce3Schristos 2800*66e63ce3Schristos trace_output (OP_PUSHPOP2); 2801*66e63ce3Schristos 2802*66e63ce3Schristos return 4; 2803*66e63ce3Schristos } 2804*66e63ce3Schristos 2805*66e63ce3Schristos /* pushmh list18 */ 2806*66e63ce3Schristos int 2807*66e63ce3Schristos OP_307E0 (void) 2808*66e63ce3Schristos { 2809*66e63ce3Schristos int i; 2810*66e63ce3Schristos 2811*66e63ce3Schristos trace_input ("pushmh", OP_PUSHPOP2, 0); 2812*66e63ce3Schristos 2813*66e63ce3Schristos /* Store the registers with lower number registers being placed at higher addresses. */ 2814*66e63ce3Schristos for (i = 0; i < 16; i++) 2815*66e63ce3Schristos if ((OP[3] & (1 << type2_regs[ i ]))) 2816*66e63ce3Schristos { 2817*66e63ce3Schristos SP -= 4; 2818*66e63ce3Schristos store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]); 2819*66e63ce3Schristos } 2820*66e63ce3Schristos 2821*66e63ce3Schristos if (OP[3] & (1 << 19)) 2822*66e63ce3Schristos { 2823*66e63ce3Schristos SP -= 8; 2824*66e63ce3Schristos 2825*66e63ce3Schristos if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) 2826*66e63ce3Schristos { 2827*66e63ce3Schristos store_mem ((SP + 4) & ~ 3, 4, FEPC); 2828*66e63ce3Schristos store_mem ( SP & ~ 3, 4, FEPSW); 2829*66e63ce3Schristos } 2830*66e63ce3Schristos else 2831*66e63ce3Schristos { 2832*66e63ce3Schristos store_mem ((SP + 4) & ~ 3, 4, EIPC); 2833*66e63ce3Schristos store_mem ( SP & ~ 3, 4, EIPSW); 2834*66e63ce3Schristos } 2835*66e63ce3Schristos } 2836*66e63ce3Schristos 2837*66e63ce3Schristos trace_output (OP_PUSHPOP2); 2838*66e63ce3Schristos 2839*66e63ce3Schristos return 4; 2840*66e63ce3Schristos } 2841*66e63ce3Schristos 2842