* armcopro.c: Remove extraneous whitespace.
* armdefs.h: Likewise.
* armfpe.h: Likewise.
* arminit.c: Likewise.
* armopts.h: Likewise.
* armos.c: Likewise.
* armos.h: Likewise.
* armrdi.c: Likewise.
* armsupp.c: Likewise.
* armvirt.c: Likewise.
* bag.c: Likewise.
* bag.h: Likewise.
* communicate.c: Likewise.
* communicate.h: Likewise.
* dbg_conf.h: Likewise.
* dbg_cp.h: Likewise.
* dbg_hif.h: Likewise.
* dbg_rdi.h: Likewise.
* gdbhost.c: Likewise.
* gdbhost.h: Likewise.
* iwmmxt.c: Likewise.
* iwmmxt.h: Likewise.
* kid.c: Likewise.
* main.c: Likewise.
* maverick.c: Likewise.
* parent.c: Likewise.
* thumbemu.c: Likewise.
* wrapper.c: Likewise.
+2015-07-14 Nick Clifton <nickc@redhat.com>
+
+ * armcopro.c: Remove extraneous whitespace.
+ * armdefs.h: Likewise.
+ * armfpe.h: Likewise.
+ * arminit.c: Likewise.
+ * armopts.h: Likewise.
+ * armos.c: Likewise.
+ * armos.h: Likewise.
+ * armrdi.c: Likewise.
+ * armsupp.c: Likewise.
+ * armvirt.c: Likewise.
+ * bag.c: Likewise.
+ * bag.h: Likewise.
+ * communicate.c: Likewise.
+ * communicate.h: Likewise.
+ * dbg_conf.h: Likewise.
+ * dbg_cp.h: Likewise.
+ * dbg_hif.h: Likewise.
+ * dbg_rdi.h: Likewise.
+ * gdbhost.c: Likewise.
+ * gdbhost.h: Likewise.
+ * iwmmxt.c: Likewise.
+ * iwmmxt.h: Likewise.
+ * kid.c: Likewise.
+ * main.c: Likewise.
+ * maverick.c: Likewise.
+ * parent.c: Likewise.
+ * thumbemu.c: Likewise.
+ * wrapper.c: Likewise.
+
2015-07-02 Nick Clifton <nickc@redhat.com>
* Makefile.in (SIM_EXTRA_CFLAGS): Revert previous delta.
/* armcopro.c -- co-processor interface: ARM6 Instruction Emulator.
Copyright (C) 1994, 2000 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* CRm must be 0. Opcode_2 can be anything. */
if (CRm != 0)
return ARMul_CANT;
- break;
+ break;
case 2:
case 3:
/* CRm must be 0. Opcode_2 must be zero. */
/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* armfpe.h -- ARMulator pre-compiled FPE: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* Array containing the Floating Point Emualtor (FPE). */
-
-
-unsigned long fpecode[] = {
+unsigned long fpecode[] =
+{
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* armopts.h -- ARMulator configuration options: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
-/* Define one of ARM60 or ARM61 */
+/* Define one of ARM60 or ARM61. */
#ifndef ARM60
#ifndef ARM61
#define ARM60
/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
exit (15);
}
}
-
+
OSptr = (struct OSblock *) state->OSptr;
OSptr->ErrorP = 0;
state->Reg[13] = ADDRSUPERSTACK; /* Set up a stack for the current mode... */
ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode... */
ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK);/* ...and for system mode. */
instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8); /* Load pc from soft vector */
-
+
for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
/* Write hardware vectors. */
ARMul_WriteWord (state, i, instr);
-
+
SWI_vector_installed = 0;
for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
returning -1 in r0 to the caller. If GDB is then used to
resume the system call the reason code will now be -1. */
return TRUE;
-
+
/* Unimplemented reason codes. */
case AngelSWI_Reason_ReadC:
case AngelSWI_Reason_TmpNam:
state->EndCondition = RDIError_SoftwareInterrupt;
state->Emulate = FALSE;
return FALSE;
- }
+ }
case 0x90: /* Reset. */
case 0x92: /* SWI. */
returning -1 in r0 to the caller. If GDB is then used to
resume the system call the reason code will now be -1. */
return TRUE;
-
+
case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
if (swi_mask & SWI_MASK_REDBOOT)
{
}
break;
}
-
+
default:
unhandled = TRUE;
}
-
+
if (unhandled)
{
if (SWI_vector_installed)
/* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* armrdi.c -- ARMulator RDI interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
{
if (trace)
fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n",
- VFP_dval (dest) - val,
+ VFP_dval (dest) - val,
VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
VFP_dval (dest) -= val;
}
{
if (trace)
fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n",
- VFP_dval (dest) + val,
+ VFP_dval (dest) + val,
VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
VFP_dval (dest) += val;
}
{
if (trace)
fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n",
- VFP_fval (dest) - val,
+ VFP_fval (dest) - val,
VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM));
VFP_fval (dest) -= val;
}
{
if (trace)
fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n",
- VFP_fval (dest) + val,
+ VFP_fval (dest) + val,
VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM));
VFP_fval (dest) += val;
}
if (BIT (8))
{
ARMdval src = VFP_dval (srcM);
-
+
VFP_dval (dest) = fabs (src);
if (trace)
fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_dval (dest));
if (BIT (16) == 0)
{
ARMdval src = VFP_dval (srcM);
-
+
if (isinf (res) && isinf (src))
{
if (res > 0.0 && src > 0.0)
if (BIT (16) == 0)
{
ARMfval src = VFP_fval (srcM);
-
+
if (isinf (res) && isinf (src))
{
if (res > 0.0 && src > 0.0)
/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* This file contains a complete ARMulator memory model, modelling a
-"virtual memory" system. A much simpler model can be found in armfast.c,
-and that model goes faster too, but has a fixed amount of memory. This
-model's memory has 64K pages, allocated on demand from a 64K entry page
-table. The routines PutWord and GetWord implement this. Pages are never
-freed as they might be needed again. A single area of memory may be
-defined to generate aborts. */
+ "virtual memory" system. A much simpler model can be found in armfast.c,
+ and that model goes faster too, but has a fixed amount of memory. This
+ model's memory has 64K pages, allocated on demand from a 64K entry page
+ table. The routines PutWord and GetWord implement this. Pages are never
+ freed as they might be needed again. A single area of memory may be
+ defined to generate aborts. */
#include "armopts.h"
#include "armos.h"
/* bag.c -- ARMulator support code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* bag.h -- ARMulator support code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* communicate.c -- ARMulator RDP comms code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* communicate.h -- ARMulator comms support defns: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* dbg_conf.h -- ARMulator debug interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
#ifndef Dbg_Conf__h
-
#define Dbg_Conf__h
typedef struct Dbg_ConfigBlock
/* dbg_cp.h -- ARMulator debug interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* dbg_hif.h -- ARMulator debug interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* dbg_rdi.h -- ARMulator RDI interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* gdbhost.c -- ARMulator RDP to gdb comms code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* gdbhost.h -- ARMulator to gdb interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface.
Copyright (C) 2002-2015 Free Software Foundation, Inc.
Contributed by matthew green (mrg@redhat.com).
-
+
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 3 of the License, or
/* #define DEBUG 1 */
-/* Intel(r) Wireless MMX(tm) technology co-processor.
+/* Intel(r) Wireless MMX(tm) technology co-processor.
It uses co-processor numbers (0 and 1). There are 16 vector registers wRx
and 16 control registers wCx. Co-processors 0 and 1 are used in MCR/MRC
to access wRx and wCx respectively. */
same sign, but the result is a different sign. */
* overflow_ptr = ( ( (result & sign_mask) && !(a1 & sign_mask) && !(a2 & sign_mask))
|| (!(result & sign_mask) && (a1 & sign_mask) && (a2 & sign_mask)));
-
+
return result;
}
IwmmxtSaturateS16 (signed int val, int * sat)
{
signed short rv;
-
+
if (val < -0x8000)
{
rv = - 0x8000;
IwmmxtSaturateS32 (signed long long val, int * sat)
{
signed long rv;
-
+
if (val < -0x80000000LL)
{
rv = -0x80000000;
#ifdef DEBUG
fprintf (stderr, "tandc\n");
-#endif
+#endif
/* The Rd field must be r15. */
if (BITS (12, 15) != 15)
ARMul_UndefInstr (state, instr);
return ARMul_DONE;
}
-
+
ARMul_SetCPSR (state, cpsr);
return ARMul_DONE;
#ifdef DEBUG
fprintf (stderr, "tbcst\n");
-#endif
+#endif
Rn = state->Reg [BITS (12, 15)];
if (BITS (12, 15) == 15)
#ifdef DEBUG
fprintf (stderr, "textrc\n");
-#endif
+#endif
/* The Rd field must be r15. */
if (BITS (12, 15) != 15)
ARMul_UndefInstr (state, instr);
return ARMul_DONE;
}
-
+
cpsr |= wCBITS (wCASF, selector, selector + 3) << 28;
ARMul_SetCPSR (state, cpsr);
#ifdef DEBUG
fprintf (stderr, "textrm\n");
-#endif
+#endif
wRn = BITS (16, 19);
sign = BIT (3);
offset = BITS (0, 2);
-
+
switch (BITS (22, 23))
{
case Bqual:
switch (offset & 3)
{
- case 0: wR [wRd] = data | (wRBITS (wRd, 16, 63) << 16); break;
+ case 0: wR [wRd] = data | (wRBITS (wRd, 16, 63) << 16); break;
case 1: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 32, 63) << 32); break;
case 2: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 48, 63) << 48); break;
case 3: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48); break;
#ifdef DEBUG
fprintf (stderr, "tmcr\n");
-#endif
+#endif
if (BITS (0, 3) != 0)
return ARMul_CANT;
/* Writing to the MUP or CUP bits clears them. */
wC [wCon] &= ~ (val & 0x3);
break;
-
+
case wCSSF:
/* Only the bottom 8 bits can be written to.
The higher bits write as zero. */
wC [wCSSF] = (val & 0xff);
wC [wCon] |= WCON_CUP;
break;
-
+
default:
wC [wCreg] = val;
wC [wCon] |= WCON_CUP;
#ifdef DEBUG
fprintf (stderr, "tmcrr\n");
-#endif
+#endif
if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15))
return ARMul_CANT;
#ifdef DEBUG
fprintf (stderr, "tmia\n");
-#endif
+#endif
if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15))
{
signed long long r;
ARMword Rm = state->Reg [BITS (0, 3)];
ARMword Rs = state->Reg [BITS (12, 15)];
-
+
if ((read_cp15_reg (15, 0, 1) & 3) != 3)
return ARMul_CANT;
#ifdef DEBUG
fprintf (stderr, "tmiaph\n");
-#endif
+#endif
if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
{
r = result;
r = EXTEND32 (r);
-
+
wR [BITS (5, 8)] += r;
a = SUBSTR (Rs, ARMword, 0, 15);
r = result;
r = EXTEND32 (r);
-
+
wR [BITS (5, 8)] += r;
wC [wCon] |= WCON_MUP;
ARMword Rm;
ARMword Rs;
long long temp;
-
+
if ((read_cp15_reg (15, 0, 1) & 3) != 3)
return ARMul_CANT;
#ifdef DEBUG
fprintf (stderr, "tmiaxy\n");
-#endif
+#endif
if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
{
#ifdef DEBUG
fprintf (stderr, "tmovmsk\n");
-#endif
+#endif
/* The CRm field must be r0. */
if (BITS (0, 3) != 0)
#ifdef DEBUG
fprintf (stderr, "tmrc\n");
-#endif
+#endif
if (BITS (0, 3) != 0)
return ARMul_CANT;
#ifdef DEBUG
fprintf (stderr, "tmrrc\n");
-#endif
+#endif
if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0))
ARMul_UndefInstr (state, instr);
#ifdef DEBUG
fprintf (stderr, "torc\n");
-#endif
+#endif
/* The Rd field must be r15. */
if (BITS (12, 15) != 15)
return ARMul_CANT;
-
+
/* The CRn field must be r3. */
if (BITS (16, 19) != 3)
return ARMul_CANT;
-
+
/* The CRm field must be r0. */
if (BITS (0, 3) != 0)
return ARMul_CANT;
ARMul_UndefInstr (state, instr);
return ARMul_DONE;
}
-
+
ARMul_SetCPSR (state, cpsr);
return ARMul_DONE;
#ifdef DEBUG
fprintf (stderr, "wacc\n");
-#endif
+#endif
wRn = BITS (16, 19);
#ifdef DEBUG
fprintf (stderr, "wadd\n");
-#endif
+#endif
/* Add two numbers using the specified function,
leaving setting the carry bit as required. */
wC [wCon] |= (WCON_MUP | WCON_CUP);
SET_wCSSFvec (satrv);
-
+
#undef ADDx
return ARMul_DONE;
#ifdef DEBUG
fprintf (stderr, "waligni\n");
-#endif
+#endif
if (shift)
wR [BITS (12, 15)] =
| (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift)));
else
wR [BITS (12, 15)] = wR [BITS (16, 19)];
-
+
wC [wCon] |= WCON_MUP;
return ARMul_DONE;
}
#ifdef DEBUG
fprintf (stderr, "walignr\n");
-#endif
+#endif
if (shift)
wR [BITS (12, 15)] =
#ifdef DEBUG
fprintf (stderr, "wand\n");
-#endif
+#endif
result = wR [BITS (16, 19)] & wR [BITS (0, 3)];
wR [BITS (12, 15)] = result;
SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
-
+
wC [wCASF] = psr;
wC [wCon] |= (WCON_CUP | WCON_MUP);
#ifdef DEBUG
fprintf (stderr, "wandn\n");
-#endif
+#endif
result = wR [BITS (16, 19)] & ~ wR [BITS (0, 3)];
wR [BITS (12, 15)] = result;
SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
-
+
wC [wCASF] = psr;
wC [wCon] |= (WCON_CUP | WCON_MUP);
#ifdef DEBUG
fprintf (stderr, "wavg2\n");
-#endif
+#endif
#define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \
+ (wRBITS (BITS ( 0, 3), (x), (y)) & (m)) \
#ifdef DEBUG
fprintf (stderr, "wcmpeq\n");
-#endif
+#endif
switch (BITS (22, 23))
{
#ifdef DEBUG
fprintf (stderr, "wcmpgt\n");
-#endif
+#endif
switch (BITS (22, 23))
{
for (i = 0; i < 8; i++)
{
signed char a, b;
-
+
a = wRBYTE (BITS (16, 19), i);
b = wRBYTE (BITS (0, 3), i);
/* Writeback into R15 is UNPREDICTABLE. */
#ifdef DEBUG
fprintf (stderr, "iWMMXt: writeback into r15\n");
-#endif
+#endif
* pFailed = 1;
}
else
{
#ifdef DEBUG
fprintf (stderr, "iWMMXt: undefined addressing mode\n");
-#endif
+#endif
* pFailed = 1;
}
}
Iwmmxt_Load_Double_Word (ARMul_State * state, ARMword address)
{
ARMdword value;
-
+
/* The address must be aligned on a 8 byte boundary. */
if (address & 0x7)
{
else
address &= ~ 3;
}
-
+
value = ARMul_LoadWordN (state, address);
if (state->Aborted)
#ifdef DEBUG
fprintf (stderr, "wldr\n");
-#endif
+#endif
address = Compute_Iwmmxt_Address (state, instr, & failed);
if (failed)
#ifdef DEBUG
fprintf (stderr, "wmac\n");
-#endif
+#endif
for (i = 0; i < 4; i++)
{
#ifdef DEBUG
fprintf (stderr, "wmadd\n");
-#endif
+#endif
for (i = 0; i < 2; i++)
{
#ifdef DEBUG
fprintf (stderr, "wmax\n");
-#endif
+#endif
switch (BITS (22, 23))
{
#ifdef DEBUG
fprintf (stderr, "wmin\n");
-#endif
+#endif
switch (BITS (22, 23))
{
wR [BITS (12, 15)] = r;
wC [wCon] |= WCON_MUP;
-
+
return ARMul_DONE;
}
#ifdef DEBUG
fprintf (stderr, "wmul\n");
-#endif
+#endif
for (i = 0; i < 4; i++)
if (BIT (21)) /* Signed. */
#ifdef DEBUG
fprintf (stderr, "wor\n");
-#endif
+#endif
result = wR [BITS (16, 19)] | wR [BITS (0, 3)];
wR [BITS (12, 15)] = result;
SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
-
+
wC [wCASF] = psr;
wC [wCon] |= (WCON_CUP | WCON_MUP);
#ifdef DEBUG
fprintf (stderr, "wpack\n");
-#endif
-
+#endif
+
switch (BITS (22, 23))
{
case Hqual:
#ifdef DEBUG
fprintf (stderr, "wror\n");
-#endif
+#endif
DECODE_G_BIT (state, instr, shift);
#ifdef DEBUG
fprintf (stderr, "wsad\n");
-#endif
+#endif
/* Z bit. */
r = BIT (20) ? 0 : (wR [BITS (12, 15)] & 0xffffffff);
#ifdef DEBUG
fprintf (stderr, "wshufh\n");
-#endif
+#endif
imm8 = (BITS (20, 23) << 4) | BITS (0, 3);
#ifdef DEBUG
fprintf (stderr, "wsll\n");
-#endif
+#endif
DECODE_G_BIT (state, instr, shift);
#ifdef DEBUG
fprintf (stderr, "wsra\n");
-#endif
+#endif
DECODE_G_BIT (state, instr, shift);
SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
}
break;
-
+
case Dqual:
if (shift > 63)
r = (wR [BITS (16, 19)] & 0x8000000000000000ULL) ? 0xffffffffffffffffULL : 0;
#ifdef DEBUG
fprintf (stderr, "wstr\n");
#endif
-
+
address = Compute_Iwmmxt_Address (state, instr, & failed);
if (failed)
return ARMul_CANT;
#ifdef DEBUG
fprintf (stderr, "wsub\n");
-#endif
+#endif
/* Subtract two numbers using the specified function,
leaving setting the carry bit as required. */
#ifdef DEBUG
fprintf (stderr, "wunpckeh\n");
-#endif
+#endif
switch (BITS (22, 23))
{
#ifdef DEBUG
fprintf (stderr, "wunpckel\n");
-#endif
+#endif
switch (BITS (22, 23))
{
#ifdef DEBUG
fprintf (stderr, "wunpckih\n");
-#endif
+#endif
switch (BITS (22, 23))
{
SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
}
break;
-
+
case Hqual:
for (i = 0; i < 2; i++)
{
#ifdef DEBUG
fprintf (stderr, "wunpckil\n");
-#endif
+#endif
switch (BITS (22, 23))
{
#ifdef DEBUG
fprintf (stderr, "wxor\n");
-#endif
+#endif
result = wR [BITS (16, 19)] ^ wR [BITS (0, 3)];
wR [BITS (12, 15)] = result;
SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
-
+
wC [wCASF] = psr;
wC [wCon] |= (WCON_CUP | WCON_MUP);
status = WMADD (instr); break;
case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
- status = WUNPCKIL (state, instr); break;
+ status = WUNPCKIL (state, instr); break;
case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
status = WUNPCKIH (state, instr); break;
case 0x012: case 0x112: case 0x412: case 0x512:
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
status = WSUB (state, instr); break;
- case 0x01e: case 0x11e: case 0x21e: case 0x31e:
+ case 0x01e: case 0x11e: case 0x21e: case 0x31e:
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
status = WPACK (state, instr); break;
case 0x201: case 0x203: case 0x205: case 0x207:
case 0x209: case 0x20b: case 0x20d: case 0x20f:
- case 0x211: case 0x213: case 0x215: case 0x217:
- case 0x219: case 0x21b: case 0x21d: case 0x21f:
+ case 0x211: case 0x213: case 0x215: case 0x217:
+ case 0x219: case 0x21b: case 0x21d: case 0x21f:
switch (BITS (16, 19))
{
case 0x0: status = TMIA (state, instr); break;
int
ARMul_HandleIwmmxt (ARMul_State * state, ARMword instr)
-{
+{
int status = ARMul_BUSY;
if (BITS (24, 27) == 0xe)
/* iwmmxt.h -- Intel(r) Wireless MMX(tm) technology co-processor interface.
Copyright (C) 2002-2015 Free Software Foundation, Inc.
Contributed by matthew green (mrg@redhat.com).
-
+
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 3 of the License, or
/* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* main.c -- top level of ARMulator: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
/* maverick.c -- Cirrus/DSP co-processor interface.
Copyright (C) 2003-2015 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-
+
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 3 of the License, or
int i;
float f;
} upper;
-
+
union
{
int i;
{
fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
fprintf (stderr, "aborting!\n");
-
+
exit (1);
}
printfdbg ("cfmvrdl\n");
printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);
printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
-
+
*value = (ARMword) DSPregs[SRC1_REG].lower.i;
break;
-
+
case 1: /* cfmvrdh */
/* Move upper half of a DF stored in a DSP reg into an Arm reg. */
printfdbg ("cfmvrdh\n");
printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);
printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
-
+
*value = (ARMword) DSPregs[SRC1_REG].upper.i;
break;
-
+
case 2: /* cfmvrs */
/* Move SF from upper half of a DSP register to an Arm register. */
*value = (ARMword) DSPregs[SRC1_REG].upper.i;
SRC1_REG,
DSPregs[SRC1_REG].upper.f);
break;
-
+
#ifdef doesnt_work
case 4: /* cfcmps */
{
*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
break;
}
-
+
case 5: /* cfcmpd */
{
double a, b;
a = DSPregs[SRC1_REG].upper.f;
b = DSPregs[SRC2_REG].upper.f;
-
+
printfdbg ("cfcmps\n");
printfdbg ("\tcomparing %f and %f\n", a, b);
a = mv_getRegDouble (SRC1_REG);
b = mv_getRegDouble (SRC2_REG);
-
+
printfdbg ("cfcmpd\n");
printfdbg ("\tcomparing %g and %g\n", a, b);
-
+
z = a == b; /* zero */
n = a < b; /* negative */
c = a > b; /* carry */
DEST_REG,
(int) *value);
break;
-
+
case 1: /* cfmvr64h */
/* Move upper half of 64bit int from Cirrus to Arm. */
*value = (ARMword) DSPregs[SRC1_REG].upper.i;
printfdbg ("cfmvr64h <-- %d\n", (int) *value);
break;
-
+
case 4: /* cfcmp32 */
{
int res;
*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
break;
}
-
+
case 5: /* cfcmp64 */
{
long long res;
*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
break;
}
-
+
default:
fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);
cirrus_not_implemented ("unknown");
case 0: /* cfmval32 */
cirrus_not_implemented ("cfmval32");
break;
-
+
case 1: /* cfmvam32 */
cirrus_not_implemented ("cfmvam32");
break;
-
+
case 2: /* cfmvah32 */
cirrus_not_implemented ("cfmvah32");
break;
-
+
case 3: /* cfmva32 */
cirrus_not_implemented ("cfmva32");
break;
-
+
case 4: /* cfmva64 */
cirrus_not_implemented ("cfmva64");
break;
-
+
case 5: /* cfmvsc32 */
cirrus_not_implemented ("cfmvsc32");
break;
-
+
default:
fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);
cirrus_not_implemented ("unknown");
printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);
DSPregs[SRC1_REG].lower.i = (int) value;
break;
-
+
case 1: /* cfmvdhr */
/* Move the upper half of a DF value from an Arm register into
the upper half of a Cirrus register. */
printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);
DSPregs[SRC1_REG].upper.i = (int) value;
break;
-
+
case 2: /* cfmvsr */
/* Move SF from Arm register into upper half of Cirrus register. */
printfdbg ("cfmvsr <-- 0x%x\n", (int) value);
DSPregs[SRC1_REG].upper.i = (int) value;
break;
-
+
default:
fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);
cirrus_not_implemented ("unknown");
printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, (int) value);
DSPregs[SRC1_REG].lower.i = (int) value;
break;
-
+
case 1: /* cfmv64hr */
/* Move upper half of a 64bit int from an ARM register into the
upper half of a DSP register. */
(int) value);
DSPregs[SRC1_REG].upper.i = (int) value;
break;
-
+
case 2: /* cfrshl32 */
printfdbg ("cfrshl32\n");
val.us = value;
else
DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -value;
break;
-
+
case 3: /* cfrshl64 */
printfdbg ("cfrshl64\n");
val.us = value;
else
mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) >> -value);
break;
-
+
default:
fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);
cirrus_not_implemented ("unknown");
case 0: /* cfmv32al */
cirrus_not_implemented ("cfmv32al");
break;
-
+
case 1: /* cfmv32am */
cirrus_not_implemented ("cfmv32am");
break;
-
+
case 2: /* cfmv32ah */
cirrus_not_implemented ("cfmv32ah");
break;
-
+
case 3: /* cfmv32a */
cirrus_not_implemented ("cfmv32a");
break;
-
+
case 4: /* cfmv64a */
cirrus_not_implemented ("cfmv64a");
break;
-
+
case 5: /* cfmv32sc */
cirrus_not_implemented ("cfmv32sc");
break;
-
+
default:
fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);
cirrus_not_implemented ("unknown");
words = 0;
return ARMul_DONE;
}
-
+
if (BIT (22))
{ /* it's a long access, get two words */
/* cfldrd */
printfdbg ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",
data, words, state->bigendSig, DEST_REG);
-
+
if (words == 0)
{
if (state->bigendSig)
else
DSPregs[DEST_REG].upper.i = (int) data;
}
-
+
++ words;
-
+
if (words == 2)
{
printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,
mv_getRegDouble (DEST_REG));
-
+
return ARMul_DONE;
}
else
else
{
/* Get just one word. */
-
+
/* cfldrs */
printfdbg ("cfldrs\n");
words = 0;
return ARMul_DONE;
}
-
+
if (BIT (22))
{
/* It's a long access, get two words. */
-
+
/* cfldr64 */
printfdbg ("cfldr64: %d\n", data);
else
DSPregs[DEST_REG].upper.i = (int) data;
}
-
+
++ words;
-
+
if (words == 2)
{
printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,
mv_getReg64int (DEST_REG));
-
+
return ARMul_DONE;
}
else
else
{
/* Get just one word. */
-
+
/* cfldr32 */
printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);
-
+
/* 32bit ints should be sign extended to 64bits when loaded. */
mv_setReg64int (DEST_REG, (long long) data);
words = 0;
return ARMul_DONE;
}
-
+
if (BIT (22))
{
/* It's a long access, get two words. */
else
*data = (ARMword) DSPregs[DEST_REG].upper.i;
}
-
+
++ words;
-
+
if (words == 2)
{
printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
mv_getRegDouble (DEST_REG));
-
+
return ARMul_DONE;
}
else
words = 0;
return ARMul_DONE;
}
-
+
if (BIT (22))
{
/* It's a long access, store two words. */
else
*data = (ARMword) DSPregs[DEST_REG].upper.i;
}
-
+
++ words;
-
+
if (words == 2)
{
printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
mv_getReg64int (DEST_REG));
-
+
return ARMul_DONE;
}
else
/* Store just one word. */
/* cfstr32 */
*data = (ARMword) DSPregs[DEST_REG].lower.i;
-
+
printfdbg ("cfstr32 MEM = %d\n", (int) *data);
return ARMul_DONE;
DSPregs[SRC1_REG].upper.f);
DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
break;
-
+
case 1: /* cfcpyd */
printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
DEST_REG,
mv_getRegDouble (SRC1_REG));
mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG));
break;
-
+
case 2: /* cfcvtds */
printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
DEST_REG,
(float) mv_getRegDouble (SRC1_REG));
DSPregs[DEST_REG].upper.f = (float) mv_getRegDouble (SRC1_REG);
break;
-
+
case 3: /* cfcvtsd */
printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
DEST_REG,
(double) DSPregs[SRC1_REG].upper.f);
mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].upper.f);
break;
-
+
case 4: /* cfcvt32s */
printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
DEST_REG,
(float) DSPregs[SRC1_REG].lower.i);
DSPregs[DEST_REG].upper.f = (float) DSPregs[SRC1_REG].lower.i;
break;
-
+
case 5: /* cfcvt32d */
printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
DEST_REG,
(double) DSPregs[SRC1_REG].lower.i);
mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].lower.i);
break;
-
+
case 6: /* cfcvt64s */
printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
DEST_REG,
(float) mv_getReg64int (SRC1_REG));
DSPregs[DEST_REG].upper.f = (float) mv_getReg64int (SRC1_REG);
break;
-
+
case 7: /* cfcvt64d */
printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
DEST_REG,
DEST_REG,
SRC1_REG,
DSPregs[SRC1_REG].upper.f * DSPregs[SRC2_REG].upper.f);
-
+
DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
* DSPregs[SRC2_REG].upper.f;
break;
-
+
case 1: /* cfmuld */
printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
DEST_REG,
mv_getRegDouble (SRC1_REG)
* mv_getRegDouble (SRC2_REG));
break;
-
+
default:
fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
cirrus_not_implemented ("unknown");
SRC1_REG,
DSPregs[DEST_REG].upper.f);
break;
-
+
case 1: /* cfabsd */
mv_setRegDouble (DEST_REG,
(mv_getRegDouble (SRC1_REG) < 0.0 ?
SRC1_REG,
mv_getRegDouble (DEST_REG));
break;
-
+
case 2: /* cfnegs */
DSPregs[DEST_REG].upper.f = -DSPregs[SRC1_REG].upper.f;
printfdbg ("cfnegs mvf%d = -mvf%d = %f\n",
SRC1_REG,
DSPregs[DEST_REG].upper.f);
break;
-
+
case 3: /* cfnegd */
mv_setRegDouble (DEST_REG,
-mv_getRegDouble (SRC1_REG));
DEST_REG,
mv_getRegDouble (DEST_REG));
break;
-
+
case 4: /* cfadds */
DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
+ DSPregs[SRC2_REG].upper.f;
SRC2_REG,
DSPregs[DEST_REG].upper.f);
break;
-
+
case 5: /* cfaddd */
mv_setRegDouble (DEST_REG,
mv_getRegDouble (SRC1_REG)
SRC2_REG,
mv_getRegDouble (DEST_REG));
break;
-
+
case 6: /* cfsubs */
DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
- DSPregs[SRC2_REG].upper.f;
SRC2_REG,
DSPregs[DEST_REG].upper.f);
break;
-
+
case 7: /* cfsubd */
mv_setRegDouble (DEST_REG,
mv_getRegDouble (SRC1_REG)
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 1: /* cfmul64 */
mv_setReg64int (DEST_REG,
mv_getReg64int (SRC1_REG)
SRC2_REG,
mv_getReg64int (DEST_REG));
break;
-
+
case 2: /* cfmac32 */
DSPregs[DEST_REG].lower.i
+= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 3: /* cfmsc32 */
DSPregs[DEST_REG].lower.i
-= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 4: /* cfcvts32 */
/* fixme: this should round */
DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
SRC1_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 5: /* cfcvtd32 */
/* fixme: this should round */
DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
SRC1_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 6: /* cftruncs32 */
DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
SRC1_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 7: /* cftruncd32 */
DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
case 2:
/* cfsh64 */
printfdbg ("cfsh64\n");
-
+
if (shift < 0)
/* Negative shift is a right shift. */
mv_setReg64int (DEST_REG,
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 1: /* cfabs64 */
mv_setReg64int (DEST_REG,
(mv_getReg64int (SRC1_REG) < 0
SRC2_REG,
mv_getReg64int (DEST_REG));
break;
-
+
case 2: /* cfneg32 */
DSPregs[DEST_REG].lower.i = -DSPregs[SRC1_REG].lower.i;
printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 3: /* cfneg64 */
mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
SRC2_REG,
mv_getReg64int (DEST_REG));
break;
-
+
case 4: /* cfadd32 */
DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
+ DSPregs[SRC2_REG].lower.i;
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 5: /* cfadd64 */
mv_setReg64int (DEST_REG,
mv_getReg64int (SRC1_REG)
SRC2_REG,
mv_getReg64int (DEST_REG));
break;
-
+
case 6: /* cfsub32 */
DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
- DSPregs[SRC2_REG].lower.i;
SRC2_REG,
DSPregs[DEST_REG].lower.i);
break;
-
+
case 7: /* cfsub64 */
mv_setReg64int (DEST_REG,
mv_getReg64int (SRC1_REG)
/* cfmadd32 */
cirrus_not_implemented ("cfmadd32");
break;
-
+
case 1:
/* cfmsub32 */
cirrus_not_implemented ("cfmsub32");
break;
-
+
case 2:
/* cfmadda32 */
cirrus_not_implemented ("cfmadda32");
break;
-
+
case 3:
/* cfmsuba32 */
cirrus_not_implemented ("cfmsuba32");
/* parent.c -- ARMulator RDP comms code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
-
+
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 3 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, see <http://www.gnu.org/licenses/>. */
fprintf (stderr, "->debugger\n");
#endif
- /* Inside this rather large if statement with simply pass on a complete
+ /* Inside this rather large if statement with simply pass on a complete
message to the ARMulator. The reason we need to pass messages on one
at a time is that we have to know whether the message is an OSOpReply
or an info(stop), so that we can take different action in those
else
{
int ror = tBITS (7, 11);
-
+
val = (1 << 7) | tBITS (0, 6);
val = (val >> ror) | (val << (32 - ror));
}
simm32 |= (-1 << 20);
break;
}
-
+
case 1: /* B.W */
{
ARMword imm10 = tBITS (0, 9);
simm32 |= (-1 << 24);
break;
}
-
+
case 2: /* BLX <label> */
{
ARMword imm10h = tBITS (0, 9);
fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
return;
}
-
+
switch (tBITS (5,12))
{
case 0x29: // TST<c>.W <Rn>,<Rm>{,<shift>}
break;
}
- case 0x50:
+ case 0x50:
{
ARMword Rd = ntBITS (8, 11);
ARMword Rn = tBITS (0, 3);
* pvalid = t_decoded;
break;
}
-
+
case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
{
ARMword Rn = tBITS (0, 3);
* pvalid = t_decoded;
break;
}
-
- case 0x52:
+
+ case 0x52:
{
ARMword Rn = tBITS (0, 3);
ARMword Rd = ntBITS (8, 11);
break;
}
- case 0x54:
+ case 0x54:
{
ARMword Rn = tBITS (0, 3);
ARMword Rd = ntBITS (8, 11);
* ainstr |= ntBITS (0, 3); // Rm
* pvalid = t_decoded;
break;
-
+
case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
{
ARMword Rn = tBITS (0, 3);
* pvalid = t_decoded;
break;
}
-
+
case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
{
* pvalid = t_decoded;
break;
}
-
+
case 0x9D: // NOP.W
tASSERT (tBITS (0, 15) == 0xF3AF);
tASSERT (ntBITS (0, 15) == 0x8000);
* pvalid = t_branch;
break;
-
+
case 0x80: // AND
case 0xA0: // TST
{
{
// AND{S}<c> <Rd>,<Rn>,#<const>
if (in_IT_block ())
- S = 0;
+ S = 0;
state->Reg[Rd] = val;
}
* pvalid = t_resolved;
break;
}
-
+
case 0xA2:
case 0x82: // MOV{S}<c>.W <Rd>,#<const>
{
if (in_IT_block ())
S = 0;
}
-
+
if (S)
ARMul_NegZero (state, result);
* pvalid = t_resolved;
break;
}
-
+
case 0xA8: // CMN
case 0x88: // ADD
{
break;
}
- case 0xAA:
+ case 0xAA:
case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
{
ARMword Rn = tBITS (0, 3);
* pvalid = t_branch;
break;
}
-
+
case 0xAB:
case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
{
}
else
{
- // SUB{S}<c>.W <Rd>,<Rn>,#<const>
+ // SUB{S}<c>.W <Rd>,<Rn>,#<const>
if (in_IT_block ())
S = 0;
CLEARV;
}
}
-
+
* pvalid = t_branch;
break;
}
tASSERT (tBIT (4) == 0);
tASSERT (ntBIT (15) == 0);
-
+
/* Note the ARM ARM indicates special cases for Rn == 15 (ADR)
and Rn == 13 (SUB SP minus immediate), but these are implemented
in exactly the same way as the normal SUBW insn. */
* pvalid = t_resolved;
break;
}
-
+
case 0xB6:
case 0x96: // MOVT<c> <Rd>,#<imm16>
{
// BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
ARMword val = state->Reg[Rn] & (mask >> lsbit);
- val <<= lsbit;
+ val <<= lsbit;
state->Reg[Rd] &= ~ mask;
state->Reg[Rd] |= val;
}
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
break;
-
+
case 0xC0: // STRB
case 0xC4: // LDRB
{
tASSERT (! (Rt == 15 && P && !U && !W));
tASSERT (! (P && U && !W));
-
+
/* LDRB<c> <Rt>,[<Rn>,#-<imm8>] => 1111 1000 0001 rrrr
LDRB<c> <Rt>,[<Rn>],#+/-<imm8> => 1111 1000 0001 rrrr
LDRB<c> <Rt>,[<Rn>,#+/-<imm8>]! => 1111 1000 0001 rrrr */
tASSERT (! (P && U && ! W));
tASSERT (! (!P && U && W && Rn == 13 && imm8 == 4 && ntBIT (11) == 0));
tASSERT (! (P && !U && W && Rn == 13 && imm8 == 4 && ntBIT (11)));
-
+
// LDR<c> <Rt>,[<Rn>,#-<imm8>]
// LDR<c> <Rt>,[<Rn>],#+/-<imm8>
// LDR<c> <Rt>,[<Rn>,#+/-<imm8>]!
* ainstr = 0xE92D0000;
* ainstr |= (1 << Rt);
-
+
Rt = Rn = 0;
}
else
* pvalid = t_branch;
break;
}
-
+
case 0xC6: // LDR.W/STR.W
{
ARMword Rn = tBITS (0, 3);
// LDRSB<c> <Rt>,<label>
ARMword imm12 = ntBITS (0, 11);
address += (U ? imm12 : - imm12);
- }
+ }
else if (U)
{
// LDRSB<c> <Rt>,[<Rn>,#<imm12>]
* pvalid = t_resolved;
break;
}
-
+
case 0xC9:
case 0xCD:// LDRSH
{
break;
}
- case 0x0D0:
+ case 0x0D0:
{
ARMword Rm = ntBITS (0, 3);
ARMword Rd = ntBITS (8, 11);
break;
}
- case 0xD2:
+ case 0xD2:
tASSERT (ntBITS (12, 15) == 15);
if (ntBIT (7))
{
* ainstr |= (ntBITS (8, 11) << 12); // Rd
* pvalid = t_decoded;
break;
-
+
case 0xD3: // ROR{S}<c>.W <Rd>,<Rn>,<Rm>
tASSERT (ntBITS (12, 15) == 15);
tASSERT (ntBITS (4, 7) == 0);
* ainstr |= (tBITS (0, 3) << 0); // Rn
* pvalid = t_decoded;
break;
-
+
case 0xD4:
{
ARMword Rn = tBITS (0, 3);
{
// REV<c>.W <Rd>,<Rm>
ARMword val = state->Reg[Rm];
-
+
tASSERT (Rm == Rn);
-
+
state->Reg [Rd] =
(val >> 24)
| ((val >> 8) & 0xFF00)
if (ntBITS (4, 7) == 1)
{
// MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
- state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
+ state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
}
else
{
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
break;
-
+
case 0xDD: // UMULL
tASSERT (tBIT (4) == 0);
tASSERT (ntBITS (4, 7) == 0);
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
break;
-
+
case 0xDF: // UMLAL
tASSERT (tBIT (4) == 0);
tASSERT (ntBITS (4, 7) == 0);
* pvalid = t_decoded;
break;
- default:
+ default:
fprintf (stderr, "(op = %x) ", tBITS (5,12));
tASSERT (0);
return;
state->Reg[Rd] += state->Reg[Rm];
break;
}
-
+
case 0x4600: // MOV<c> <Rd>,<Rm>
{
// instr [15, 8] = 0100 0110
state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
break;
}
-
+
case 0xb660: /* cpsie */
case 0xb670: /* cpsid */
case 0xbac0: /* revsh */
return t_branch;
}
-
+
old_tinstr = tinstr;
if (trace)
fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
* ainstr |= tBITS (8, 10) << 16;
* ainstr |= tBITS (0, 7);
break;
-
+
case 6:
case 7:
* ainstr = tBIT (11)
int i;
float f;
} upper;
-
+
union
{
int i;
len -= 4;
memory += 4;
regval = 0;
- }
+ }
return length;
}
trace = 1;
continue;
}
-
+
if (strcmp (ptr, "-z") == 0)
{
/* Remove this option from the argv array. */
trace_funcs = 1;
continue;
}
-
+
if (strcmp (ptr, "-d") == 0)
{
/* Remove this option from the argv array. */
for (arg = i; arg < argc; arg ++)
argv[arg] = argv[arg + 1];
argc --;
-
+
ptr = argv[i];
}
else
ptr += sizeof SWI_SWITCH;
swi_mask = 0;
-
+
while (* ptr)
{
int i;
if (* ptr != 0)
fprintf (stderr, "Ignoring swi options: %s\n", ptr);
-
+
/* Remove this option from the argv array. */
for (arg = i; arg < argc; arg ++)
argv[arg] = argv[arg + 1];
"Missing argument to -m option\n");
return NULL;
}
-
}
}