| 1 | /* This file is part of the program psim. |
| 2 | |
| 3 | Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney |
| 4 | |
| 5 | This program is free software; you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by |
| 7 | the Free Software Foundation; either version 3 of the License, or |
| 8 | (at your option) any later version. |
| 9 | |
| 10 | This program is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | GNU General Public License for more details. |
| 14 | |
| 15 | You should have received a copy of the GNU General Public License |
| 16 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
| 17 | |
| 18 | */ |
| 19 | |
| 20 | /* Additional, and optional expressions. */ |
| 21 | #ifdef WITH_ALTIVEC |
| 22 | #include "altivec_expression.h" |
| 23 | #endif |
| 24 | #ifdef WITH_E500 |
| 25 | #include "e500_expression.h" |
| 26 | #endif |
| 27 | |
| 28 | /* 32bit target expressions: |
| 29 | |
| 30 | Each calculation is performed three times using each of the |
| 31 | signed64, unsigned64 and long integer types. The macro ALU_END |
| 32 | (in _ALU_RESULT_VAL) then selects which of the three alternative |
| 33 | results will be used in the final assignment of the target |
| 34 | register. As this selection is determined at compile time by |
| 35 | fields in the instruction (OE, EA, Rc) the compiler has sufficient |
| 36 | information to firstly simplify the selection code into a single |
| 37 | case and then back anotate the equations and hence eliminate any |
| 38 | resulting dead code. That dead code being the calculations that, |
| 39 | as it turned out were not in the end needed. |
| 40 | |
| 41 | 64bit arrithemetic is used firstly because it allows the use of |
| 42 | gcc's efficient long long operators (typically efficiently output |
| 43 | inline) and secondly because the resultant answer will contain in |
| 44 | the low 32bits the answer while in the high 32bits is either carry |
| 45 | or status information. */ |
| 46 | |
| 47 | /* 64bit target expressions: |
| 48 | |
| 49 | Unfortunatly 128bit arrithemetic isn't that common. Consequently |
| 50 | the 32/64 bit trick can not be used. Instead all calculations are |
| 51 | required to retain carry/overflow information in separate |
| 52 | variables. Even with this restriction it is still possible for the |
| 53 | trick of letting the compiler discard the calculation of unneeded |
| 54 | values */ |
| 55 | |
| 56 | |
| 57 | /* Macro's to type cast 32bit constants to 64bits */ |
| 58 | #define SIGNED64(val) ((signed64)(signed32)(val)) |
| 59 | #define UNSIGNED64(val) ((unsigned64)(unsigned32)(val)) |
| 60 | |
| 61 | |
| 62 | /* Start a section of ALU code */ |
| 63 | |
| 64 | #define ALU_BEGIN(val) \ |
| 65 | { \ |
| 66 | natural_word alu_val; \ |
| 67 | unsigned64 alu_carry_val; \ |
| 68 | signed64 alu_overflow_val; \ |
| 69 | ALU_SET(val) |
| 70 | |
| 71 | |
| 72 | /* assign the result to the target register */ |
| 73 | |
| 74 | #define ALU_END(TARG,CA,OE,Rc) \ |
| 75 | { /* select the result to use */ \ |
| 76 | signed_word const alu_result = _ALU_RESULT_VAL(CA,OE,Rc); \ |
| 77 | /* determine the overflow bit if needed */ \ |
| 78 | if (OE) { \ |
| 79 | if ((((unsigned64)(alu_overflow_val & BIT64(0))) \ |
| 80 | >> 32) \ |
| 81 | == (alu_overflow_val & BIT64(32))) \ |
| 82 | XER &= (~xer_overflow); \ |
| 83 | else \ |
| 84 | XER |= (xer_summary_overflow | xer_overflow); \ |
| 85 | } \ |
| 86 | /* Update the carry bit if needed */ \ |
| 87 | if (CA) { \ |
| 88 | XER = ((XER & ~xer_carry) \ |
| 89 | | SHUFFLED32((alu_carry_val >> 32), 31, xer_carry_bit)); \ |
| 90 | /* if (alu_carry_val & BIT64(31)) \ |
| 91 | XER |= (xer_carry); \ |
| 92 | else \ |
| 93 | XER &= (~xer_carry); */ \ |
| 94 | } \ |
| 95 | TRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n", \ |
| 96 | (long)alu_result, (long)alu_result, (long)XER)); \ |
| 97 | /* Update the Result Conditions if needed */ \ |
| 98 | CR0_COMPARE(alu_result, 0, Rc); \ |
| 99 | /* assign targ same */ \ |
| 100 | TARG = alu_result; \ |
| 101 | }} |
| 102 | |
| 103 | /* select the result from the different options */ |
| 104 | |
| 105 | #define _ALU_RESULT_VAL(CA,OE,Rc) (WITH_TARGET_WORD_BITSIZE == 64 \ |
| 106 | ? alu_val \ |
| 107 | : (OE \ |
| 108 | ? alu_overflow_val \ |
| 109 | : (CA \ |
| 110 | ? alu_carry_val \ |
| 111 | : alu_val))) |
| 112 | |
| 113 | |
| 114 | /* More basic alu operations */ |
| 115 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 116 | #define ALU_SET(val) \ |
| 117 | do { \ |
| 118 | alu_val = val; \ |
| 119 | alu_carry_val = ((unsigned64)alu_val) >> 32; \ |
| 120 | alu_overflow_val = ((signed64)alu_val) >> 32; \ |
| 121 | } while (0) |
| 122 | #endif |
| 123 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 124 | #define ALU_SET(val) \ |
| 125 | do { \ |
| 126 | alu_val = val; \ |
| 127 | alu_carry_val = (unsigned32)(alu_val); \ |
| 128 | alu_overflow_val = (signed32)(alu_val); \ |
| 129 | } while (0) |
| 130 | #endif |
| 131 | |
| 132 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 133 | #define ALU_ADD(val) \ |
| 134 | do { \ |
| 135 | unsigned64 alu_lo = (UNSIGNED64(alu_val) \ |
| 136 | + UNSIGNED64(val)); \ |
| 137 | signed alu_carry = ((alu_lo & BIT(31)) != 0); \ |
| 138 | alu_carry_val = (alu_carry_val \ |
| 139 | + UNSIGNED64(EXTRACTED(val, 0, 31)) \ |
| 140 | + alu_carry); \ |
| 141 | alu_overflow_val = (alu_overflow_val \ |
| 142 | + SIGNED64(EXTRACTED(val, 0, 31)) \ |
| 143 | + alu_carry); \ |
| 144 | alu_val = alu_val + val; \ |
| 145 | } while (0) |
| 146 | #endif |
| 147 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 148 | #define ALU_ADD(val) \ |
| 149 | do { \ |
| 150 | alu_val += val; \ |
| 151 | alu_carry_val += (unsigned32)(val); \ |
| 152 | alu_overflow_val += (signed32)(val); \ |
| 153 | } while (0) |
| 154 | #endif |
| 155 | |
| 156 | |
| 157 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 158 | #define ALU_ADD_CA \ |
| 159 | do { \ |
| 160 | signed carry = MASKED32(XER, xer_carry_bit, xer_carry_bit) != 0; \ |
| 161 | ALU_ADD(carry); \ |
| 162 | } while (0) |
| 163 | #endif |
| 164 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 165 | #define ALU_ADD_CA \ |
| 166 | do { \ |
| 167 | signed carry = MASKED32(XER, xer_carry_bit, xer_carry_bit) != 0; \ |
| 168 | ALU_ADD(carry); \ |
| 169 | } while (0) |
| 170 | #endif |
| 171 | |
| 172 | |
| 173 | #if 0 |
| 174 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 175 | #endif |
| 176 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 177 | #define ALU_SUB(val) \ |
| 178 | do { \ |
| 179 | alu_val -= val; \ |
| 180 | alu_carry_val -= (unsigned32)(val); \ |
| 181 | alu_overflow_val -= (signed32)(val); \ |
| 182 | } while (0) |
| 183 | #endif |
| 184 | #endif |
| 185 | |
| 186 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 187 | #endif |
| 188 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 189 | #define ALU_OR(val) \ |
| 190 | do { \ |
| 191 | alu_val |= val; \ |
| 192 | alu_carry_val = (unsigned32)(alu_val); \ |
| 193 | alu_overflow_val = (signed32)(alu_val); \ |
| 194 | } while (0) |
| 195 | #endif |
| 196 | |
| 197 | |
| 198 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 199 | #endif |
| 200 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 201 | #define ALU_XOR(val) \ |
| 202 | do { \ |
| 203 | alu_val ^= val; \ |
| 204 | alu_carry_val = (unsigned32)(alu_val); \ |
| 205 | alu_overflow_val = (signed32)(alu_val); \ |
| 206 | } while (0) |
| 207 | #endif |
| 208 | |
| 209 | |
| 210 | #if 0 |
| 211 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 212 | #endif |
| 213 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 214 | #define ALU_NEGATE \ |
| 215 | do { \ |
| 216 | alu_val = -alu_val; \ |
| 217 | alu_carry_val = -alu_carry_val; \ |
| 218 | alu_overflow_val = -alu_overflow_val; \ |
| 219 | } while(0) |
| 220 | #endif |
| 221 | #endif |
| 222 | |
| 223 | |
| 224 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 225 | #endif |
| 226 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 227 | #define ALU_AND(val) \ |
| 228 | do { \ |
| 229 | alu_val &= val; \ |
| 230 | alu_carry_val = (unsigned32)(alu_val); \ |
| 231 | alu_overflow_val = (signed32)(alu_val); \ |
| 232 | } while (0) |
| 233 | #endif |
| 234 | |
| 235 | |
| 236 | #if (WITH_TARGET_WORD_BITSIZE == 64) |
| 237 | #define ALU_NOT \ |
| 238 | do { \ |
| 239 | signed64 new_alu_val = ~alu_val; \ |
| 240 | ALU_SET(new_alu_val); \ |
| 241 | } while (0) |
| 242 | #endif |
| 243 | #if (WITH_TARGET_WORD_BITSIZE == 32) |
| 244 | #define ALU_NOT \ |
| 245 | do { \ |
| 246 | signed new_alu_val = ~alu_val; \ |
| 247 | ALU_SET(new_alu_val); \ |
| 248 | } while(0) |
| 249 | #endif |
| 250 | |
| 251 | |
| 252 | /* Macros for updating the condition register */ |
| 253 | |
| 254 | #define CR1_UPDATE(Rc) \ |
| 255 | do { \ |
| 256 | if (Rc) { \ |
| 257 | CR_SET(1, EXTRACTED32(FPSCR, fpscr_fx_bit, fpscr_ox_bit)); \ |
| 258 | } \ |
| 259 | } while (0) |
| 260 | |
| 261 | |
| 262 | #define _DO_CR_COMPARE(LHS, RHS) \ |
| 263 | (((LHS) < (RHS)) \ |
| 264 | ? cr_i_negative \ |
| 265 | : (((LHS) > (RHS)) \ |
| 266 | ? cr_i_positive \ |
| 267 | : cr_i_zero)) |
| 268 | |
| 269 | #define CR_SET(REG, VAL) MBLIT32(CR, REG*4, REG*4+3, VAL) |
| 270 | #define CR_FIELD(REG) EXTRACTED32(CR, REG*4, REG*4+3) |
| 271 | #define CR_SET_XER_SO(REG, VAL) \ |
| 272 | do { \ |
| 273 | creg new_bits = ((XER & xer_summary_overflow) \ |
| 274 | ? (cr_i_summary_overflow | VAL) \ |
| 275 | : VAL); \ |
| 276 | CR_SET(REG, new_bits); \ |
| 277 | } while(0) |
| 278 | |
| 279 | #define CR_COMPARE(REG, LHS, RHS) \ |
| 280 | do { \ |
| 281 | creg new_bits = ((XER & xer_summary_overflow) \ |
| 282 | ? (cr_i_summary_overflow | _DO_CR_COMPARE(LHS,RHS)) \ |
| 283 | : _DO_CR_COMPARE(LHS,RHS)); \ |
| 284 | CR_SET(REG, new_bits); \ |
| 285 | } while (0) |
| 286 | |
| 287 | #define CR0_COMPARE(LHS, RHS, Rc) \ |
| 288 | do { \ |
| 289 | if (Rc) { \ |
| 290 | CR_COMPARE(0, LHS, RHS); \ |
| 291 | TRACE(trace_alu, \ |
| 292 | ("CR=0x%08lx, LHS=%ld, RHS=%ld\n", \ |
| 293 | (unsigned long)CR, (long)LHS, (long)RHS)); \ |
| 294 | } \ |
| 295 | } while (0) |
| 296 | |
| 297 | |
| 298 | |
| 299 | /* Bring data in from the cold */ |
| 300 | |
| 301 | #define MEM(SIGN, EA, NR_BYTES) \ |
| 302 | ((SIGN##_##NR_BYTES) vm_data_map_read_##NR_BYTES(cpu_data_map(processor), EA, \ |
| 303 | processor, cia)) \ |
| 304 | |
| 305 | #define STORE(EA, NR_BYTES, VAL) \ |
| 306 | do { \ |
| 307 | vm_data_map_write_##NR_BYTES(cpu_data_map(processor), EA, VAL, \ |
| 308 | processor, cia); \ |
| 309 | } while (0) |
| 310 | |
| 311 | |
| 312 | |
| 313 | /* some FPSCR update macros. */ |
| 314 | |
| 315 | #define FPSCR_BEGIN \ |
| 316 | { \ |
| 317 | fpscreg old_fpscr UNUSED = FPSCR |
| 318 | |
| 319 | #define FPSCR_END(Rc) { \ |
| 320 | /* always update VX */ \ |
| 321 | if ((FPSCR & fpscr_vx_bits)) \ |
| 322 | FPSCR |= fpscr_vx; \ |
| 323 | else \ |
| 324 | FPSCR &= ~fpscr_vx; \ |
| 325 | /* always update FEX */ \ |
| 326 | if (((FPSCR & fpscr_vx) && (FPSCR & fpscr_ve)) \ |
| 327 | || ((FPSCR & fpscr_ox) && (FPSCR & fpscr_oe)) \ |
| 328 | || ((FPSCR & fpscr_ux) && (FPSCR & fpscr_ue)) \ |
| 329 | || ((FPSCR & fpscr_zx) && (FPSCR & fpscr_ze)) \ |
| 330 | || ((FPSCR & fpscr_xx) && (FPSCR & fpscr_xe))) \ |
| 331 | FPSCR |= fpscr_fex; \ |
| 332 | else \ |
| 333 | FPSCR &= ~fpscr_fex; \ |
| 334 | CR1_UPDATE(Rc); \ |
| 335 | /* interrupt enabled? */ \ |
| 336 | if ((MSR & (msr_floating_point_exception_mode_0 \ |
| 337 | | msr_floating_point_exception_mode_1)) \ |
| 338 | && (FPSCR & fpscr_fex)) \ |
| 339 | program_interrupt(processor, cia, \ |
| 340 | floating_point_enabled_program_interrupt); \ |
| 341 | }} |
| 342 | |
| 343 | #define FPSCR_SET(REG, VAL) MBLIT32(FPSCR, REG*4, REG*4+3, VAL) |
| 344 | #define FPSCR_FIELD(REG) EXTRACTED32(FPSCR, REG*4, REG*4+3) |
| 345 | |
| 346 | #define FPSCR_SET_FPCC(VAL) MBLIT32(FPSCR, fpscr_fpcc_bit, fpscr_fpcc_bit+3, VAL) |
| 347 | |
| 348 | /* Handle various exceptions */ |
| 349 | |
| 350 | #define FPSCR_OR_VX(VAL) \ |
| 351 | do { \ |
| 352 | /* NOTE: VAL != 0 */ \ |
| 353 | FPSCR |= (VAL); \ |
| 354 | FPSCR |= fpscr_fx; \ |
| 355 | } while (0) |
| 356 | |
| 357 | #define FPSCR_SET_OX(COND) \ |
| 358 | do { \ |
| 359 | if (COND) { \ |
| 360 | FPSCR |= fpscr_ox; \ |
| 361 | FPSCR |= fpscr_fx; \ |
| 362 | } \ |
| 363 | else \ |
| 364 | FPSCR &= ~fpscr_ox; \ |
| 365 | } while (0) |
| 366 | |
| 367 | #define FPSCR_SET_UX(COND) \ |
| 368 | do { \ |
| 369 | if (COND) { \ |
| 370 | FPSCR |= fpscr_ux; \ |
| 371 | FPSCR |= fpscr_fx; \ |
| 372 | } \ |
| 373 | else \ |
| 374 | FPSCR &= ~fpscr_ux; \ |
| 375 | } while (0) |
| 376 | |
| 377 | #define FPSCR_SET_ZX(COND) \ |
| 378 | do { \ |
| 379 | if (COND) { \ |
| 380 | FPSCR |= fpscr_zx; \ |
| 381 | FPSCR |= fpscr_fx; \ |
| 382 | } \ |
| 383 | else \ |
| 384 | FPSCR &= ~fpscr_zx; \ |
| 385 | } while (0) |
| 386 | |
| 387 | #define FPSCR_SET_XX(COND) \ |
| 388 | do { \ |
| 389 | if (COND) { \ |
| 390 | FPSCR |= fpscr_xx; \ |
| 391 | FPSCR |= fpscr_fx; \ |
| 392 | } \ |
| 393 | } while (0) |
| 394 | |
| 395 | /* Note: code using SET_FI must also explicitly call SET_XX */ |
| 396 | |
| 397 | #define FPSCR_SET_FR(COND) do { \ |
| 398 | if (COND) \ |
| 399 | FPSCR |= fpscr_fr; \ |
| 400 | else \ |
| 401 | FPSCR &= ~fpscr_fr; \ |
| 402 | } while (0) |
| 403 | |
| 404 | #define FPSCR_SET_FI(COND) \ |
| 405 | do { \ |
| 406 | if (COND) { \ |
| 407 | FPSCR |= fpscr_fi; \ |
| 408 | } \ |
| 409 | else \ |
| 410 | FPSCR &= ~fpscr_fi; \ |
| 411 | } while (0) |
| 412 | |
| 413 | #define FPSCR_SET_FPRF(VAL) \ |
| 414 | do { \ |
| 415 | FPSCR = (FPSCR & ~fpscr_fprf) | (VAL); \ |
| 416 | } while (0) |