Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_r4300.def
diff --git a/source/mupen64plus-core/src/r4300/interpreter_r4300.def b/source/mupen64plus-core/src/r4300/interpreter_r4300.def
new file mode 100644 (file)
index 0000000..a78fa63
--- /dev/null
@@ -0,0 +1,800 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *   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, &reg[0],  0, 0)
+DECLARE_JUMP(JAL, (PC->f.j.inst_index<<2) | ((PCADDR+4) & 0xF0000000), 1, &reg[31], 0, 0)
+DECLARE_JUMP(BEQ,     PCADDR + (iimmediate+1)*4, irs == irt, &reg[0], 0, 0)
+DECLARE_JUMP(BNE,     PCADDR + (iimmediate+1)*4, irs != irt, &reg[0], 0, 0)
+DECLARE_JUMP(BLEZ,    PCADDR + (iimmediate+1)*4, irs <= 0,   &reg[0], 0, 0)
+DECLARE_JUMP(BGTZ,    PCADDR + (iimmediate+1)*4, irs > 0,    &reg[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, &reg[0], 1, 0)
+DECLARE_JUMP(BNEL,    PCADDR + (iimmediate+1)*4, irs != irt, &reg[0], 1, 0)
+DECLARE_JUMP(BLEZL,   PCADDR + (iimmediate+1)*4, irs <= 0,   &reg[0], 1, 0)
+DECLARE_JUMP(BGTZL,   PCADDR + (iimmediate+1)*4, irs > 0,    &reg[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();
+}