|
|
1.1 root 1: /*
2: * MIPS emulation memory micro-operations for qemu.
1.1.1.5 ! root 3: *
1.1 root 4: * Copyright (c) 2004-2005 Jocelyn Mayer
5: *
6: * This library is free software; you can redistribute it and/or
7: * modify it under the terms of the GNU Lesser General Public
8: * License as published by the Free Software Foundation; either
9: * version 2 of the License, or (at your option) any later version.
10: *
11: * This library is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * Lesser General Public License for more details.
15: *
16: * You should have received a copy of the GNU Lesser General Public
17: * License along with this library; if not, write to the Free Software
18: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19: */
20:
21: /* Standard loads and stores */
22: void glue(op_lb, MEMSUFFIX) (void)
23: {
24: T0 = glue(ldsb, MEMSUFFIX)(T0);
1.1.1.5 ! root 25: FORCE_RET();
1.1 root 26: }
27:
28: void glue(op_lbu, MEMSUFFIX) (void)
29: {
30: T0 = glue(ldub, MEMSUFFIX)(T0);
1.1.1.5 ! root 31: FORCE_RET();
1.1 root 32: }
33:
34: void glue(op_sb, MEMSUFFIX) (void)
35: {
36: glue(stb, MEMSUFFIX)(T0, T1);
1.1.1.5 ! root 37: FORCE_RET();
1.1 root 38: }
39:
40: void glue(op_lh, MEMSUFFIX) (void)
41: {
42: T0 = glue(ldsw, MEMSUFFIX)(T0);
1.1.1.5 ! root 43: FORCE_RET();
1.1 root 44: }
45:
46: void glue(op_lhu, MEMSUFFIX) (void)
47: {
48: T0 = glue(lduw, MEMSUFFIX)(T0);
1.1.1.5 ! root 49: FORCE_RET();
1.1 root 50: }
51:
52: void glue(op_sh, MEMSUFFIX) (void)
53: {
54: glue(stw, MEMSUFFIX)(T0, T1);
1.1.1.5 ! root 55: FORCE_RET();
1.1 root 56: }
57:
58: void glue(op_lw, MEMSUFFIX) (void)
59: {
60: T0 = glue(ldl, MEMSUFFIX)(T0);
1.1.1.5 ! root 61: FORCE_RET();
1.1 root 62: }
63:
1.1.1.3 root 64: void glue(op_lwu, MEMSUFFIX) (void)
65: {
1.1.1.5 ! root 66: T0 = (uint32_t)glue(ldl, MEMSUFFIX)(T0);
! 67: FORCE_RET();
1.1.1.3 root 68: }
69:
1.1 root 70: void glue(op_sw, MEMSUFFIX) (void)
71: {
72: glue(stl, MEMSUFFIX)(T0, T1);
1.1.1.5 ! root 73: FORCE_RET();
1.1 root 74: }
75:
1.1.1.2 root 76: /* "half" load and stores. We must do the memory access inline,
77: or fault handling won't work. */
1.1.1.5 ! root 78:
! 79: #ifdef TARGET_WORDS_BIGENDIAN
! 80: #define GET_LMASK(v) ((v) & 3)
! 81: #define GET_OFFSET(addr, offset) (addr + (offset))
! 82: #else
! 83: #define GET_LMASK(v) (((v) & 3) ^ 3)
! 84: #define GET_OFFSET(addr, offset) (addr - (offset))
! 85: #endif
! 86:
1.1 root 87: void glue(op_lwl, MEMSUFFIX) (void)
88: {
1.1.1.5 ! root 89: target_ulong tmp;
! 90:
! 91: tmp = glue(ldub, MEMSUFFIX)(T0);
! 92: T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
! 93:
! 94: if (GET_LMASK(T0) <= 2) {
! 95: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
! 96: T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
! 97: }
! 98:
! 99: if (GET_LMASK(T0) <= 1) {
! 100: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
! 101: T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
! 102: }
! 103:
! 104: if (GET_LMASK(T0) == 0) {
! 105: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
! 106: T1 = (T1 & 0xFFFFFF00) | tmp;
! 107: }
! 108: T1 = (int32_t)T1;
! 109: FORCE_RET();
1.1 root 110: }
111:
112: void glue(op_lwr, MEMSUFFIX) (void)
113: {
1.1.1.5 ! root 114: target_ulong tmp;
! 115:
! 116: tmp = glue(ldub, MEMSUFFIX)(T0);
! 117: T1 = (T1 & 0xFFFFFF00) | tmp;
! 118:
! 119: if (GET_LMASK(T0) >= 1) {
! 120: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
! 121: T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
! 122: }
! 123:
! 124: if (GET_LMASK(T0) >= 2) {
! 125: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
! 126: T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
! 127: }
! 128:
! 129: if (GET_LMASK(T0) == 3) {
! 130: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
! 131: T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
! 132: }
! 133: T1 = (int32_t)T1;
! 134: FORCE_RET();
1.1 root 135: }
136:
137: void glue(op_swl, MEMSUFFIX) (void)
138: {
1.1.1.5 ! root 139: glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 24));
! 140:
! 141: if (GET_LMASK(T0) <= 2)
! 142: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16));
! 143:
! 144: if (GET_LMASK(T0) <= 1)
! 145: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8));
! 146:
! 147: if (GET_LMASK(T0) == 0)
! 148: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)T1);
! 149:
! 150: FORCE_RET();
1.1 root 151: }
152:
153: void glue(op_swr, MEMSUFFIX) (void)
154: {
1.1.1.5 ! root 155: glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
! 156:
! 157: if (GET_LMASK(T0) >= 1)
! 158: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
! 159:
! 160: if (GET_LMASK(T0) >= 2)
! 161: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
! 162:
! 163: if (GET_LMASK(T0) == 3)
! 164: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
! 165:
! 166: FORCE_RET();
1.1 root 167: }
168:
169: void glue(op_ll, MEMSUFFIX) (void)
170: {
171: T1 = T0;
172: T0 = glue(ldl, MEMSUFFIX)(T0);
173: env->CP0_LLAddr = T1;
1.1.1.5 ! root 174: FORCE_RET();
1.1 root 175: }
176:
177: void glue(op_sc, MEMSUFFIX) (void)
178: {
179: CALL_FROM_TB0(dump_sc);
1.1.1.5 ! root 180: if (T0 & 0x3) {
! 181: env->CP0_BadVAddr = T0;
! 182: CALL_FROM_TB1(do_raise_exception, EXCP_AdES);
! 183: }
1.1 root 184: if (T0 == env->CP0_LLAddr) {
185: glue(stl, MEMSUFFIX)(T0, T1);
186: T0 = 1;
187: } else {
188: T0 = 0;
189: }
1.1.1.5 ! root 190: FORCE_RET();
1.1 root 191: }
1.1.1.3 root 192:
1.1.1.5 ! root 193: #if defined(TARGET_MIPS64)
1.1.1.4 root 194: void glue(op_ld, MEMSUFFIX) (void)
195: {
196: T0 = glue(ldq, MEMSUFFIX)(T0);
1.1.1.5 ! root 197: FORCE_RET();
1.1.1.4 root 198: }
199:
200: void glue(op_sd, MEMSUFFIX) (void)
201: {
202: glue(stq, MEMSUFFIX)(T0, T1);
1.1.1.5 ! root 203: FORCE_RET();
1.1.1.4 root 204: }
205:
206: /* "half" load and stores. We must do the memory access inline,
207: or fault handling won't work. */
1.1.1.5 ! root 208:
! 209: #ifdef TARGET_WORDS_BIGENDIAN
! 210: #define GET_LMASK64(v) ((v) & 7)
! 211: #else
! 212: #define GET_LMASK64(v) (((v) & 7) ^ 7)
! 213: #endif
! 214:
1.1.1.4 root 215: void glue(op_ldl, MEMSUFFIX) (void)
216: {
1.1.1.5 ! root 217: uint64_t tmp;
! 218:
! 219: tmp = glue(ldub, MEMSUFFIX)(T0);
! 220: T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
! 221:
! 222: if (GET_LMASK64(T0) <= 6) {
! 223: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
! 224: T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
! 225: }
! 226:
! 227: if (GET_LMASK64(T0) <= 5) {
! 228: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
! 229: T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
! 230: }
! 231:
! 232: if (GET_LMASK64(T0) <= 4) {
! 233: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
! 234: T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
! 235: }
! 236:
! 237: if (GET_LMASK64(T0) <= 3) {
! 238: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 4));
! 239: T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
! 240: }
! 241:
! 242: if (GET_LMASK64(T0) <= 2) {
! 243: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 5));
! 244: T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
! 245: }
! 246:
! 247: if (GET_LMASK64(T0) <= 1) {
! 248: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 6));
! 249: T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
! 250: }
! 251:
! 252: if (GET_LMASK64(T0) == 0) {
! 253: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 7));
! 254: T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
! 255: }
! 256:
! 257: FORCE_RET();
1.1.1.4 root 258: }
259:
260: void glue(op_ldr, MEMSUFFIX) (void)
261: {
1.1.1.5 ! root 262: uint64_t tmp;
! 263:
! 264: tmp = glue(ldub, MEMSUFFIX)(T0);
! 265: T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
! 266:
! 267: if (GET_LMASK64(T0) >= 1) {
! 268: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
! 269: T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
! 270: }
! 271:
! 272: if (GET_LMASK64(T0) >= 2) {
! 273: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
! 274: T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
! 275: }
! 276:
! 277: if (GET_LMASK64(T0) >= 3) {
! 278: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
! 279: T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
! 280: }
! 281:
! 282: if (GET_LMASK64(T0) >= 4) {
! 283: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -4));
! 284: T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
! 285: }
! 286:
! 287: if (GET_LMASK64(T0) >= 5) {
! 288: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -5));
! 289: T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
! 290: }
! 291:
! 292: if (GET_LMASK64(T0) >= 6) {
! 293: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -6));
! 294: T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
! 295: }
! 296:
! 297: if (GET_LMASK64(T0) == 7) {
! 298: tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -7));
! 299: T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
! 300: }
! 301:
! 302: FORCE_RET();
1.1.1.4 root 303: }
304:
305: void glue(op_sdl, MEMSUFFIX) (void)
306: {
1.1.1.5 ! root 307: glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 56));
! 308:
! 309: if (GET_LMASK64(T0) <= 6)
! 310: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48));
! 311:
! 312: if (GET_LMASK64(T0) <= 5)
! 313: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40));
! 314:
! 315: if (GET_LMASK64(T0) <= 4)
! 316: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32));
! 317:
! 318: if (GET_LMASK64(T0) <= 3)
! 319: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24));
! 320:
! 321: if (GET_LMASK64(T0) <= 2)
! 322: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16));
! 323:
! 324: if (GET_LMASK64(T0) <= 1)
! 325: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8));
! 326:
! 327: if (GET_LMASK64(T0) <= 0)
! 328: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 7), (uint8_t)T1);
! 329:
! 330: FORCE_RET();
1.1.1.4 root 331: }
332:
333: void glue(op_sdr, MEMSUFFIX) (void)
334: {
1.1.1.5 ! root 335: glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
! 336:
! 337: if (GET_LMASK64(T0) >= 1)
! 338: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
! 339:
! 340: if (GET_LMASK64(T0) >= 2)
! 341: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
! 342:
! 343: if (GET_LMASK64(T0) >= 3)
! 344: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
! 345:
! 346: if (GET_LMASK64(T0) >= 4)
! 347: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32));
! 348:
! 349: if (GET_LMASK64(T0) >= 5)
! 350: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40));
! 351:
! 352: if (GET_LMASK64(T0) >= 6)
! 353: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48));
! 354:
! 355: if (GET_LMASK64(T0) == 7)
! 356: glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56));
! 357:
! 358: FORCE_RET();
1.1.1.4 root 359: }
360:
361: void glue(op_lld, MEMSUFFIX) (void)
362: {
363: T1 = T0;
364: T0 = glue(ldq, MEMSUFFIX)(T0);
365: env->CP0_LLAddr = T1;
1.1.1.5 ! root 366: FORCE_RET();
1.1.1.4 root 367: }
368:
369: void glue(op_scd, MEMSUFFIX) (void)
370: {
371: CALL_FROM_TB0(dump_sc);
1.1.1.5 ! root 372: if (T0 & 0x7) {
! 373: env->CP0_BadVAddr = T0;
! 374: CALL_FROM_TB1(do_raise_exception, EXCP_AdES);
! 375: }
1.1.1.4 root 376: if (T0 == env->CP0_LLAddr) {
377: glue(stq, MEMSUFFIX)(T0, T1);
378: T0 = 1;
379: } else {
380: T0 = 0;
381: }
1.1.1.5 ! root 382: FORCE_RET();
1.1.1.4 root 383: }
1.1.1.5 ! root 384: #endif /* TARGET_MIPS64 */
1.1.1.4 root 385:
1.1.1.3 root 386: void glue(op_lwc1, MEMSUFFIX) (void)
387: {
388: WT0 = glue(ldl, MEMSUFFIX)(T0);
1.1.1.5 ! root 389: FORCE_RET();
1.1.1.3 root 390: }
391: void glue(op_swc1, MEMSUFFIX) (void)
392: {
393: glue(stl, MEMSUFFIX)(T0, WT0);
1.1.1.5 ! root 394: FORCE_RET();
1.1.1.3 root 395: }
396: void glue(op_ldc1, MEMSUFFIX) (void)
397: {
398: DT0 = glue(ldq, MEMSUFFIX)(T0);
1.1.1.5 ! root 399: FORCE_RET();
1.1.1.3 root 400: }
401: void glue(op_sdc1, MEMSUFFIX) (void)
402: {
403: glue(stq, MEMSUFFIX)(T0, DT0);
1.1.1.5 ! root 404: FORCE_RET();
! 405: }
! 406: void glue(op_luxc1, MEMSUFFIX) (void)
! 407: {
! 408: DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
! 409: FORCE_RET();
! 410: }
! 411: void glue(op_suxc1, MEMSUFFIX) (void)
! 412: {
! 413: glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
! 414: FORCE_RET();
1.1.1.3 root 415: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.