--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus - interpreter_r4300.def *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+DECLARE_JUMP(J, (PC->f.j.inst_index<<2) | ((PCADDR+4) & 0xF0000000), 1, ®[0], 0, 0)
+DECLARE_JUMP(JAL, (PC->f.j.inst_index<<2) | ((PCADDR+4) & 0xF0000000), 1, ®[31], 0, 0)
+DECLARE_JUMP(BEQ, PCADDR + (iimmediate+1)*4, irs == irt, ®[0], 0, 0)
+DECLARE_JUMP(BNE, PCADDR + (iimmediate+1)*4, irs != irt, ®[0], 0, 0)
+DECLARE_JUMP(BLEZ, PCADDR + (iimmediate+1)*4, irs <= 0, ®[0], 0, 0)
+DECLARE_JUMP(BGTZ, PCADDR + (iimmediate+1)*4, irs > 0, ®[0], 0, 0)
+
+DECLARE_INSTRUCTION(ADDI)
+{
+ irt32 = irs32 + iimmediate;
+ sign_extended(irt);
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(ADDIU)
+{
+ irt32 = irs32 + iimmediate;
+ sign_extended(irt);
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SLTI)
+{
+ if (irs < iimmediate) irt = 1;
+ else irt = 0;
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SLTIU)
+{
+ if ((unsigned long long)irs < (unsigned long long)((long long)iimmediate))
+ irt = 1;
+ else irt = 0;
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(ANDI)
+{
+ irt = irs & (unsigned short)iimmediate;
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(ORI)
+{
+ irt = irs | (unsigned short)iimmediate;
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(XORI)
+{
+ irt = irs ^ (unsigned short)iimmediate;
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(LUI)
+{
+ irt32 = iimmediate << 16;
+ sign_extended(irt);
+ ADD_TO_PC(1);
+}
+
+DECLARE_JUMP(BEQL, PCADDR + (iimmediate+1)*4, irs == irt, ®[0], 1, 0)
+DECLARE_JUMP(BNEL, PCADDR + (iimmediate+1)*4, irs != irt, ®[0], 1, 0)
+DECLARE_JUMP(BLEZL, PCADDR + (iimmediate+1)*4, irs <= 0, ®[0], 1, 0)
+DECLARE_JUMP(BGTZL, PCADDR + (iimmediate+1)*4, irs > 0, ®[0], 1, 0)
+
+DECLARE_INSTRUCTION(DADDI)
+{
+ irt = irs + iimmediate;
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DADDIU)
+{
+ irt = irs + iimmediate;
+ ADD_TO_PC(1);
+}
+
+// TODOXXX refactor the following functions to remove the
+// lsaddr and lsrpt locals. this may lead to a small speedup too
+
+DECLARE_INSTRUCTION(LDL)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 7)
+ {
+ case 0:
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_dword_in_memory();
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFF) | (word << 8);
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFF) | (word << 16);
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFF) | (word << 24);
+ break;
+ case 4:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFF) | (word << 32);
+ break;
+ case 5:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFLL) | (word << 40);
+ break;
+ case 6:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFLL) | (word << 48);
+ break;
+ case 7:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFFFLL) | (word << 56);
+ break;
+ }
+}
+
+DECLARE_INSTRUCTION(LDR)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 7)
+ {
+ case 0:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFFF00LL) | (word >> 56);
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFFF0000LL) | (word >> 48);
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFF000000LL) | (word >> 40);
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFF00000000LL) | (word >> 32);
+ break;
+ case 4:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFF0000000000LL) | (word >> 24);
+ break;
+ case 5:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFF000000000000LL) | (word >> 16);
+ break;
+ case 6:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &word;
+ read_dword_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFF00000000000000LL) | (word >> 8);
+ break;
+ case 7:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = (unsigned long long *) lsrtp;
+ read_dword_in_memory();
+ break;
+ }
+}
+
+DECLARE_INSTRUCTION(LB)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_byte_in_memory();
+ if (address)
+ sign_extendedb(*lsrtp);
+}
+
+DECLARE_INSTRUCTION(LH)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_hword_in_memory();
+ if (address)
+ sign_extendedh(*lsrtp);
+}
+
+DECLARE_INSTRUCTION(LWL)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 3)
+ {
+ case 0:
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_word_in_memory();
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &word;
+ read_word_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFF) | (word << 8);
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &word;
+ read_word_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFF) | (word << 16);
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &word;
+ read_word_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFF) | (word << 24);
+ break;
+ }
+ if(address)
+ sign_extended(*lsrtp);
+}
+
+DECLARE_INSTRUCTION(LW)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_word_in_memory();
+ if (address)
+ sign_extended(*lsrtp);
+}
+
+DECLARE_INSTRUCTION(LBU)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_byte_in_memory();
+}
+
+DECLARE_INSTRUCTION(LHU)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_hword_in_memory();
+}
+
+DECLARE_INSTRUCTION(LWR)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 3)
+ {
+ case 0:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &word;
+ read_word_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFFFFF00LL) | ((word >> 24) & 0xFF);
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &word;
+ read_word_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFFFF0000LL) | ((word >> 16) & 0xFFFF);
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &word;
+ read_word_in_memory();
+ if(address)
+ *lsrtp = (*lsrtp & 0xFFFFFFFFFF000000LL) | ((word >> 8) & 0XFFFFFF);
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = (unsigned long long *) lsrtp;
+ read_word_in_memory();
+ if(address)
+ sign_extended(*lsrtp);
+ }
+}
+
+DECLARE_INSTRUCTION(LWU)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_word_in_memory();
+}
+
+DECLARE_INSTRUCTION(SB)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ cpu_byte = (unsigned char)(*lsrtp & 0xFF);
+ write_byte_in_memory();
+ CHECK_MEMORY();
+}
+
+DECLARE_INSTRUCTION(SH)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ hword = (unsigned short)(*lsrtp & 0xFFFF);
+ write_hword_in_memory();
+ CHECK_MEMORY();
+}
+
+DECLARE_INSTRUCTION(SWL)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int old_word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 3)
+ {
+ case 0:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ word = (unsigned int)*lsrtp;
+ write_word_in_memory();
+ CHECK_MEMORY();
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &old_word;
+ read_word_in_memory();
+ if(address)
+ {
+ word = ((unsigned int)*lsrtp >> 8) | ((unsigned int) old_word & 0xFF000000);
+ write_word_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &old_word;
+ read_word_in_memory();
+ if(address)
+ {
+ word = ((unsigned int)*lsrtp >> 16) | ((unsigned int) old_word & 0xFFFF0000);
+ write_word_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 3:
+ address = (unsigned int) lsaddr;
+ cpu_byte = (unsigned char)(*lsrtp >> 24);
+ write_byte_in_memory();
+ CHECK_MEMORY();
+ break;
+ }
+}
+
+DECLARE_INSTRUCTION(SW)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ word = (unsigned int)(*lsrtp & 0xFFFFFFFF);
+ write_word_in_memory();
+ CHECK_MEMORY();
+}
+
+DECLARE_INSTRUCTION(SDL)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int old_word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 7)
+ {
+ case 0:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ dword = *lsrtp;
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 8)|(old_word & 0xFF00000000000000LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 16)|(old_word & 0xFFFF000000000000LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 24)|(old_word & 0xFFFFFF0000000000LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 4:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 32)|(old_word & 0xFFFFFFFF00000000LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 5:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 40)|(old_word & 0xFFFFFFFFFF000000LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 6:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 48)|(old_word & 0xFFFFFFFFFFFF0000LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 7:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = ((unsigned long long)*lsrtp >> 56)|(old_word & 0xFFFFFFFFFFFFFF00LL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ }
+}
+
+DECLARE_INSTRUCTION(SDR)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int old_word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 7)
+ {
+ case 0:
+ address = (unsigned int) lsaddr;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 56) | (old_word & 0x00FFFFFFFFFFFFFFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 48) | (old_word & 0x0000FFFFFFFFFFFFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 40) | (old_word & 0x000000FFFFFFFFFFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 32) | (old_word & 0x00000000FFFFFFFFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 4:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 24) | (old_word & 0x0000000000FFFFFFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 5:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 16) | (old_word & 0x000000000000FFFFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 6:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ rdword = &old_word;
+ read_dword_in_memory();
+ if(address)
+ {
+ dword = (*lsrtp << 8) | (old_word & 0x00000000000000FFLL);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 7:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFF8;
+ dword = *lsrtp;
+ write_dword_in_memory();
+ CHECK_MEMORY();
+ break;
+ }
+}
+
+DECLARE_INSTRUCTION(SWR)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ unsigned long long int old_word = 0;
+ ADD_TO_PC(1);
+ switch ((lsaddr) & 3)
+ {
+ case 0:
+ address = (unsigned int) lsaddr;
+ rdword = &old_word;
+ read_word_in_memory();
+ if(address)
+ {
+ word = ((unsigned int)*lsrtp << 24) | ((unsigned int) old_word & 0x00FFFFFF);
+ write_word_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 1:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &old_word;
+ read_word_in_memory();
+ if(address)
+ {
+ word = ((unsigned int)*lsrtp << 16) | ((unsigned int) old_word & 0x0000FFFF);
+ write_word_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 2:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ rdword = &old_word;
+ read_word_in_memory();
+ if(address)
+ {
+ word = ((unsigned int)*lsrtp << 8) | ((unsigned int) old_word & 0x000000FF);
+ write_word_in_memory();
+ CHECK_MEMORY();
+ }
+ break;
+ case 3:
+ address = ((unsigned int) lsaddr) & 0xFFFFFFFC;
+ word = (unsigned int)*lsrtp;
+ write_word_in_memory();
+ CHECK_MEMORY();
+ break;
+ }
+}
+
+DECLARE_INSTRUCTION(CACHE)
+{
+ ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(LL)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_word_in_memory();
+ if (address)
+ {
+ sign_extended(*lsrtp);
+ llbit = 1;
+ }
+}
+
+DECLARE_INSTRUCTION(LWC1)
+{
+ const unsigned char lslfft = lfft;
+ const unsigned int lslfaddr = (unsigned int)(lfoffset + reg[lfbase]);
+ unsigned long long int temp;
+ if (check_cop1_unusable()) return;
+ ADD_TO_PC(1);
+ address = (unsigned int) lslfaddr;
+ rdword = &temp;
+ read_word_in_memory();
+ if (address)
+ *((int*)reg_cop1_simple[lslfft]) = (int) *rdword;
+}
+
+DECLARE_INSTRUCTION(LDC1)
+{
+ const unsigned char lslfft = lfft;
+ const unsigned int lslfaddr = (unsigned int)(lfoffset + reg[lfbase]);
+ if (check_cop1_unusable()) return;
+ ADD_TO_PC(1);
+ address = (unsigned int) lslfaddr;
+ rdword = (unsigned long long *)reg_cop1_double[lslfft];
+ read_dword_in_memory();
+}
+
+DECLARE_INSTRUCTION(LD)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ rdword = (unsigned long long *) lsrtp;
+ read_dword_in_memory();
+}
+
+DECLARE_INSTRUCTION(SC)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ if(llbit)
+ {
+ address = (unsigned int) lsaddr;
+ word = (unsigned int)(*lsrtp & 0xFFFFFFFF);
+ write_word_in_memory();
+ CHECK_MEMORY();
+ llbit = 0;
+ *lsrtp = 1;
+ }
+ else
+ {
+ *lsrtp = 0;
+ }
+}
+
+DECLARE_INSTRUCTION(SWC1)
+{
+ const unsigned char lslfft = lfft;
+ const unsigned int lslfaddr = (unsigned int)(lfoffset + reg[lfbase]);
+ if (check_cop1_unusable()) return;
+ ADD_TO_PC(1);
+ address = (unsigned int) lslfaddr;
+ word = *((int*)reg_cop1_simple[lslfft]);
+ write_word_in_memory();
+ CHECK_MEMORY();
+}
+
+DECLARE_INSTRUCTION(SDC1)
+{
+ const unsigned char lslfft = lfft;
+ const unsigned int lslfaddr = (unsigned int)(lfoffset + reg[lfbase]);
+ if (check_cop1_unusable()) return;
+ ADD_TO_PC(1);
+ address = (unsigned int) lslfaddr;
+ dword = *((unsigned long long*)reg_cop1_double[lslfft]);
+ write_dword_in_memory();
+ CHECK_MEMORY();
+}
+
+DECLARE_INSTRUCTION(SD)
+{
+ const unsigned int lsaddr = (unsigned int)(iimmediate + irs32);
+ long long int *lsrtp = PC->f.i.rt;
+ ADD_TO_PC(1);
+ address = (unsigned int) lsaddr;
+ dword = *lsrtp;
+ write_dword_in_memory();
+ CHECK_MEMORY();
+}