diff options
| author | 2025-09-05 02:06:54 +1000 | |
|---|---|---|
| committer | 2025-09-05 02:06:54 +1000 | |
| commit | a418fb42671cbb8979e4952c6e5ec56c99b3358c (patch) | |
| tree | e49ae1021de5971405b7acac4c2b2617459bb486 | |
| parent | 2f02333f11ad59d2c7cb296550c428a6e8f96bbc (diff) | |
Various small improvements:
misc/crystal.cpp: Added lamp outputs used by Office Yeoin Cheonha and
Urachacha Mudaeri, and fixed button order/names for Urachacha Mudaeri.
cpu/uml.cpp: Added a couple of simplification rules. ADDC's inputs are
commutative, and TEST with an immediate zero operand effectively ignores
the other operand.
namco/namcos23.cpp: Treat spinny things as a dial rather than half a
mouse.
cpu/arm7: Removed the recompiler that had never been completed.
cpu/drcumlsh.h: Removed helpers for generating the unimplemented JMPH
instrcution. Trying to use it would cause a compile error.
docs: Documented the most common DRC UML integer arithmetic and logical
instructions.
| -rw-r--r-- | docs/source/techspecs/uml_instructions.rst | 1313 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/ap2010cpu.cpp | 2 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/ap2010cpu.h | 4 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/arm7.cpp | 4 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/arm7.h | 236 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/arm7drc.hxx | 1812 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/arm7fe.hxx | 458 | ||||
| -rw-r--r-- | src/devices/cpu/arm7/arm7tdrc.hxx | 1592 | ||||
| -rw-r--r-- | src/devices/cpu/drcumlsh.h | 2 | ||||
| -rw-r--r-- | src/devices/cpu/uml.cpp | 40 | ||||
| -rw-r--r-- | src/devices/machine/vrender0.cpp | 6 | ||||
| -rw-r--r-- | src/mame/midway/midyunit.cpp | 27 | ||||
| -rw-r--r-- | src/mame/misc/crystal.cpp | 32 | ||||
| -rw-r--r-- | src/mame/namco/namcos23.cpp | 4 | ||||
| -rw-r--r-- | src/mame/pinball/criter75.cpp | 13 |
15 files changed, 1037 insertions, 4508 deletions
diff --git a/docs/source/techspecs/uml_instructions.rst b/docs/source/techspecs/uml_instructions.rst index 5d379dd1c60..47140e74be0 100644 --- a/docs/source/techspecs/uml_instructions.rst +++ b/docs/source/techspecs/uml_instructions.rst @@ -18,6 +18,13 @@ Front-ends translate code running on the guest CPUs to UML instructions, and back-ends convert the UML instructions to a form that can be executed or interpreted on the host system. +Many UML instruction have multiple instruction sizes. Integer instructions +default to 32-bit size. Adding a ``D`` or ``d`` prefix to the mnemonic changes +to 64-bit size (double word). Floating-point instructions use the mnemonic +prefix/suffix ``FS`` or ``fs`` for IEEE 754 32-bit format (single precision) or +or the prefix/suffix ``FD`` or ``fd`` for IEEE 754 64-bit format (double +precision). + .. _umlinst-flow: @@ -49,17 +56,16 @@ string Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-nop: @@ -79,17 +85,16 @@ No operation. Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-label: @@ -120,17 +125,16 @@ label (label number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-handle: @@ -163,17 +167,16 @@ handle (code handle) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-hash: @@ -210,17 +213,16 @@ pc (32-bit – immediate, map variable) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-jmp: @@ -255,17 +257,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-callh: @@ -300,17 +301,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-exh: @@ -350,17 +350,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -398,17 +397,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-hashjmp: @@ -457,17 +455,16 @@ handle (code handle) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-exit: @@ -500,17 +497,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -548,17 +544,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. .. _umlinst-debug: @@ -591,17 +586,16 @@ pc (32-bit – memory, integer register, immediate, map variable) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -629,17 +623,16 @@ left in final code. Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. .. _umlinst-datamove: @@ -679,17 +672,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -733,17 +725,16 @@ cond (condition) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -780,17 +771,16 @@ src (32-bit or 64-bit – memory, integer register) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-icopyf: @@ -821,17 +811,16 @@ src (32-bit or 64-bit – memory, floating point register) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-load: @@ -878,17 +867,16 @@ scale (index scale) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-loads: @@ -935,17 +923,16 @@ scale (index scale) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-store: @@ -991,17 +978,16 @@ scale (index scale) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-fload: @@ -1039,17 +1025,16 @@ index (32-bit – memory, integer register, immediate, map variable) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-fstore: @@ -1087,17 +1072,16 @@ src (32-bit or 64-bit – memory, floating point register) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-getexp: @@ -1125,17 +1109,16 @@ dst (32-bit – memory, integer register) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-mapvar: @@ -1165,17 +1148,16 @@ value (32-bit – immediate, map variable) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Unchanged. | -+---------------+------------+ -| overflow (V) | Unchanged. | -+---------------+------------+ -| zero (Z) | Unchanged. | -+---------------+------------+ -| sign (S) | Unchanged. | -+---------------+------------+ -| unordered (U) | Unchanged. | -+---------------+------------+ +carry (C) + Unchanged. +overflow (V) + Unchanged. +zero (Z) + Unchanged. +sign (S) + Unchanged. +unordered (U) + Unchanged. .. _umlinst-recover: @@ -1209,17 +1191,16 @@ mapvar (map variable) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. .. _umlinst-memaccess: @@ -1269,17 +1250,16 @@ space (address space number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -1329,17 +1309,16 @@ space (address space number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -1391,17 +1370,16 @@ space (address space number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -1452,17 +1430,16 @@ space (address space number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -1510,17 +1487,16 @@ space (address space number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ @@ -1564,19 +1540,652 @@ space (address space number) Flags ^^^^^ -+---------------+------------+ -| carry (C) | Undefined. | -+---------------+------------+ -| overflow (V) | Undefined. | -+---------------+------------+ -| zero (Z) | Undefined. | -+---------------+------------+ -| sign (S) | Undefined. | -+---------------+------------+ -| unordered (U) | Undefined. | -+---------------+------------+ +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Undefined. +sign (S) + Undefined. +unordered (U) + Undefined. Simplification rules ^^^^^^^^^^^^^^^^^^^^ * Immediate values for the ``addr`` operand are truncated to 32 bits. + + +.. _umlinst-intarith: + +Integer arithmetic and logic +---------------------------- + +.. _umlinst-add: + +ADD +~~~ + +Add two integers. + ++---------------------------+---------------------------------------+ +| Disassembly | Usage | ++===========================+=======================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| add dst,src1,src2 | UML_ADD(block, dst, src1, src2); | +| dadd dst,src1,src2 | UML_DADD(block, dst, src1, src2); | ++---------------------------+---------------------------------------+ + +Calculates ``dst = src1 + src2``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the sum will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first addend. +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The second addend. + +Flags +^^^^^ + +carry (C) + Set in the case of arithmetic carry out of the most significant bit, or + cleared otherwise (unsigned overflow). +overflow (V) + Set in the case of signed two’s complement overflow, or cleared otherwise. +zero (Z) + Set if the result is zero, or cleared otherwise. +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`MOV <umlinst-mov>`, :ref:`AND <umlinst-and>` or :ref:`OR + <umlinst-or>` if the ``src1`` and ``src2`` operands are both immediate values + and the carry and overflow flags are not required. +* Converted to :ref:`MOV <umlinst-mov>` or :ref:`AND <umlinst-and>` if the + ``src1`` operand or ``src2`` operand is the immediate value zero and the carry + and overflow flags are not required. +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. +* If the ``src2`` and ``dst`` operands refer to the same register or memory + location, the ``src1`` and ``src2`` operands are exchanged. +* If the ``src1`` operand is an immediate value and the ``src2`` operand is not + an immediate value, the ``src1`` and ``src2`` operands are exchanged. + +.. _umlinst-addc: + +ADDC +~~~~ + +Add two integers and the carry flag. + ++---------------------------+----------------------------------------+ +| Disassembly | Usage | ++===========================+========================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| addc dst,src1,src2 | UML_ADDC(block, dst, src1, src2); | +| daddc dst,src1,src2 | UML_DADDC(block, dst, src1, src2); | ++---------------------------+----------------------------------------+ + +Calculates ``dst = src1 + src2 + C``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the sum will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first addend. +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The second addend. + +Flags +^^^^^ + +carry (C) + Set in the case of arithmetic carry out of the most significant bit, or + cleared otherwise (unsigned overflow). +overflow (V) + Set in the case of signed two’s complement overflow, or cleared otherwise. +zero (Z) + Set if the result is zero, or cleared otherwise. +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. +* If the ``src2`` and ``dst`` operands refer to the same register or memory + location, the ``src1`` and ``src2`` operands are exchanged. +* If the ``src1`` operand is an immediate value and the ``src2`` operand is not + an immediate value, the ``src1`` and ``src2`` operands are exchanged. + +.. _umlinst-sub: + +SUB +~~~ + +Subtract an integer from another integer. + ++---------------------------+---------------------------------------+ +| Disassembly | Usage | ++===========================+=======================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| sub dst,src1,src2 | UML_SUB(block, dst, src1, src2); | +| dsub dst,src1,src2 | UML_DSUB(block, dst, src1, src2); | ++---------------------------+---------------------------------------+ + +Calculates ``dst = src1 - src2``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the difference will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The minuend (the value to subtract from). +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The subtrahend (the value to subtract). + +Flags +^^^^^ + +carry (C) + Set if the subtrahend is a larger unsigned value than the minuend, or + cleared otherwise (unsigned overflow, or arithmetic borrow). +overflow (V) + Set in the case of signed two’s complement overflow, or cleared otherwise. +zero (Z) + Set if the result is zero, or cleared otherwise (set if the minuend and + subtrahend are equal, or cleared otherwise). +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. +* Converted to :ref:`MOV <umlinst-mov>`, :ref:`AND <umlinst-and>` or :ref:`OR + <umlinst-or>` if the ``src1`` and ``src2`` operands are both immediate values + and the carry and overflow flags are not required. +* Converted to :ref:`MOV <umlinst-mov>` or :ref:`AND <umlinst-and>` if the + ``src2`` operand is the immediate value zero and the carry and overflow flags + are not required. + +.. _umlinst-subb: + +SUBB +~~~~ + +Subtract an integer and the carry flag from another integer. + ++---------------------------+----------------------------------------+ +| Disassembly | Usage | ++===========================+========================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| subb dst,src1,src2 | UML_SUBB(block, dst, src1, src2); | +| dsubb dst,src1,src2 | UML_DSUBB(block, dst, src1, src2); | ++---------------------------+----------------------------------------+ + +Calculates ``dst = src1 - src2 - C``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the difference will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The minuend (the value to subtract from). +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The subtrahend (the value to subtract). + +Flags +^^^^^ + +carry (C) + Set if the subtrahend plus the carry flag is a larger unsigned value than + the minuend, or cleared otherwise (unsigned overflow, or arithmetic borrow). +overflow (V) + Set in the case of signed two’s complement overflow, or cleared otherwise. +zero (Z) + Set if the result is zero, or cleared otherwise (set if the minuend is equal + to the subtrahend plus the carry flag, or cleared otherwise). +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. + +.. _umlinst-cmp: + +CMP +~~~ + +Compare two integers and set the flags as though they were subtracted. + ++-----------------------+----------------------------------+ +| Disassembly | Usage | ++=======================+==================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| cmp src1,src2 | UML_CMP(block, src1, src2); | +| dcmp src1,src2 | UML_DCMP(block, src1, src2); | ++-----------------------+----------------------------------+ + +Sets the flags based on calculating ``src1 - src2`` but discards the result of +the subtraction. + +Operands +^^^^^^^^ + +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first left-hand side value to compare, or the minuend (the value to + subtract from). +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first right-hand side value to compare, or the subtrahend (the value to + subtract). + +Flags +^^^^^ + +carry (C) + Set if the unsigned value of the ``src1`` operand is smaller than the + unsigned value of the ``src2`` operand, or cleared otherwise. +overflow (V) + Set if subtracting the value of the ``src2`` operand from the value of the + ``src1`` operand would result in two’s complement overflow, or cleared + otherwise. +zero (Z) + Set if the values of the ``src1`` and ``src2`` operands are equal, or + cleared otherwise. +sign (S) + Set to the value of the most significant bit of the result of subtracting + the value of the ``src2`` operand from the value of the ``src1`` operand + (set if the result would be a negative signed integer, or cleared + otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`NOP <umlinst-nop>` if no flags are required. +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. + +.. _umlinst-and: + +AND +~~~ + +Calculate the bitwise logical conjunction of two integers (result bits will be +set if the corresponding bits are set in both inputs). + ++---------------------------+---------------------------------------+ +| Disassembly | Usage | ++===========================+=======================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| and dst,src1,src2 | UML_AND(block, dst, src1, src2); | +| dand dst,src1,src2 | UML_DAND(block, dst, src1, src2); | ++---------------------------+---------------------------------------+ + +Calculates ``dst = src1 ∧ src2``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the logical conjunction will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first input. +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The second input. + +Flags +^^^^^ + +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Set if the result is zero, or cleared otherwise. +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`MOV <umlinst-mov>` if the ``src1`` and ``src2`` operands + refer to the same memory location or register, the ``src1`` and ``src2`` + operands are both immediate values or one of them is an immediate value with + all bits set or no bits set and flags are not required. +* Converted to :ref:`OR <umlinst-or>` if the ``src1`` and ``src2`` operands are + both immediate values with all bits set and flags are required. +* Converted to :ref:`TEST <umlinst-test>` if the instruction size is 64 bits or + the ``dst`` operand refers to a memory location, one of the ``src1`` and + ``src2`` operands refer to the same memory location or register as ``dst``, + the other source operand refers to the same memory location or register or is + an immediate value with all bits set, and flags are required. +* If the ``src1`` and ``src2`` operands are both immediate values, the + conjunction is not zero and flags are required, ``src1`` is replaced with the + conjunction and ``src2`` is set to an immediate value with all bits set. +* If the ``src1`` and ``src2`` operands are both immediate values and the + conjunction is zero or either the ``src1`` or ``src2`` operand is the + immediate value zero and flags are required, ``src1`` is set to refer to the + same memory location or register as ``dst`` and ``src2`` is set to the + immediate value zero. +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. +* If the ``src2`` and ``dst`` operands refer to the same register or memory + location, the ``src1`` and ``src2`` operands are exchanged. +* If the ``src1`` operand is an immediate value and the ``src2`` operand is not + an immediate value, the ``src1`` and ``src2`` operands are exchanged. + +.. _umlinst-test: + +TEST +~~~~ + +Set the flags based on the bitwise logical conjunction of two integers. + ++-----------------------+-----------------------------------+ +| Disassembly | Usage | ++=======================+===================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| test src1,src2 | UML_TEST(block, src1, src2); | +| dtest src1,src2 | UML_DTEST(block, src1, src2); | ++-----------------------+-----------------------------------+ + +Sets the flags based on calculating ``src1 ∧ src2`` but discards the result of +the conjunction. + +Operands +^^^^^^^^ + +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first input. +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The second input. + +Flags +^^^^^ + +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Set if the result of the conjunction is zero, or cleared otherwise. +sign (S) + Set if the most significant bit is set in both inputs, or cleared otherwise + (set if the both inputs are negative signed integers, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`NOP <umlinst-nop>` if flags are not required. +* If the ``src1`` and ``src2`` operands are both immediate values and the + bitwise logical conjunction is not zero, the ``src1`` operand is set to the + conjunction and the ``src2`` operand is set to an immediate value with all + bits set. +* If either of the ``src1`` and ``src2`` operands is the immediate value zero or + the ``src1`` and ``src2`` operands are both immediate values and the bitwise + logical conjunction is zero, the ``src1`` and ``src2`` operands are both set + to the immediate value zero. +* If the ``src1`` and ``src2`` operands refer to the same memory location or + register, the ``src2`` operand is set to an immediate value with all bits set. +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. +* If the ``src1`` operand is an immediate value and the ``src2`` operand is not + an immediate value, the ``src1`` and ``src2`` operands are exchanged. + +.. _umlinst-or: + +OR +~~ + +Calculate the bitwise logical inclusive disjunction of two integers (result bits +will be set if the corresponding bits are set in either input). + ++---------------------------+--------------------------------------+ +| Disassembly | Usage | ++===========================+======================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| or dst,src1,src2 | UML_OR(block, dst, src1, src2); | +| dor dst,src1,src2 | UML_DOR(block, dst, src1, src2); | ++---------------------------+--------------------------------------+ + +Calculates ``dst = src1 ∨ src2``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the logical inclusive disjunction will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first input. +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The second input. + +Flags +^^^^^ + +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Set if the result is zero, or cleared otherwise. +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`MOV <umlinst-mov>` if the ``src1`` and ``src2`` operands + are both immediate values or one of the ``src1`` or ``src2`` operands is an + immediate value with all bits set and flags are not required. +* Converted to :ref:`AND <umlinst-and>` if the ``src1`` and ``src2`` operands + are both immediate values and the inclusive disjunction does not have all + bits set and flags are required. +* Converted to :ref:`MOV <umlinst-mov>`, :ref:`AND <umlinst-and>` or :ref:`TEST + <umlinst-test>` if the ``src1`` and ``src2`` operands refer to the same memory + location or register or if one of the ``src1`` and ``src2`` operands is the + immediate value zero. +* If one of the ``src1`` and ``src2`` operands is an immediate value with all + bits set or the ``src1`` and ``src2`` operands are both immediate values and + the inclusive disjunction has all bits set and flags are required, ``src1`` is + set to refer to the same memory location or register as ``dst`` and ``src2`` + is set to an immediate value with all bits set. +* Immediate values for the ``src1`` and ``src2`` operands are truncated to the + instruction size. +* If the ``src2`` and ``dst`` operands refer to the same register or memory + location, the ``src1`` and ``src2`` operands are exchanged. +* If the ``src1`` operand is an immediate value and the ``src2`` operand is not + an immediate value, the ``src1`` and ``src2`` operands are exchanged. + +.. _umlinst-xor: + +XOR +~~~ + +Calculate the bitwise logical exclusive disjunction of two integers (result bits +will be set if the corresponding bit is set in one input and unset in the other +input). + ++---------------------------+---------------------------------------+ +| Disassembly | Usage | ++===========================+=======================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| xor dst,src1,src2 | UML_XOR(block, dst, src1, src2); | +| dxor dst,src1,src2 | UML_DXOR(block, dst, src1, src2); | ++---------------------------+---------------------------------------+ + +Calculates ``dst = src1 ⊻ src2``. + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the logical exclusive disjunction will be stored. +src1 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The first input. +src2 (32-bit or 64-bit – memory, integer register, immediate, map variable) + The second input. + +Flags +^^^^^ + +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Set if the result is zero, or cleared otherwise. +sign (S) + Set to the value of the most significant bit of the result (set if the + result is a negative signed integer, or cleared otherwise). +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`MOV <umlinst-mov>`, :ref:`AND <umlinst-and>`, :ref:`TEST + <umlinst-test>` or :ref:`OR <umlinst-or>` if the ``src1`` and ``src2`` + operands are both immediate values, if one of the ``src1`` and ``src2`` + operands is the immediate value zero or if the ``src1`` and ``src2`` operands + refer to the same memory location or register. + +.. _umlinst-lzcnt: + +LZCNT +~~~~~ + +Count the number of contiguous left-aligned zero bits in an integer (count +leading zeroes). + ++---------------------+----------------------------------+ +| Disassembly | Usage | ++=====================+==================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| lzcnt dst,src | UML_LZCNT(block, dst, src); | +| dlzcnt dst,src | UML_DLZCNT(block, dst, src); | ++---------------------+----------------------------------+ + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the result will be stored +src (32-bit or 64-bit – memory, integer register, immediate, map variable) + The input value in which to count left-aligned zero bits. + +Flags +^^^^^ + +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Set if the result is zero, or cleared otherwise (set to the most significant + bit of the input). +sign (S) + Undefined. +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`MOV <umlinst-mov>` or :ref:`AND <umlinst-and>` if the + ``src`` operand is an immediate value. + +.. _umlinst-tzcnt: + +TZCNT +~~~~~ + +Count the number of contiguous right-aligned zero bits in an integer (count +trailing zeroes). + ++---------------------+----------------------------------+ +| Disassembly | Usage | ++=====================+==================================+ +| .. code-block:: | .. code-block:: C++ | +| | | +| tzcnt dst,src | UML_TZCNT(block, dst, src); | +| dtzcnt dst,src | UML_DTZCNT(block, dst, src); | ++---------------------+----------------------------------+ + +Operands +^^^^^^^^ + +dst (32-bit or 64-bit – memory, integer register) + The destination where the result will be stored +src (32-bit or 64-bit – memory, integer register, immediate, map variable) + The input value in which to count right-aligned zero bits. + +Flags +^^^^^ + +carry (C) + Undefined. +overflow (V) + Undefined. +zero (Z) + Set if the result is zero, or cleared otherwise (set to the least + significant bit of the input). +sign (S) + Undefined. +unordered (U) + Undefined. + +Simplification rules +^^^^^^^^^^^^^^^^^^^^ + +* Converted to :ref:`MOV <umlinst-mov>` or :ref:`AND <umlinst-and>` if the + ``src`` operand is an immediate value. diff --git a/src/devices/cpu/arm7/ap2010cpu.cpp b/src/devices/cpu/arm7/ap2010cpu.cpp index 0a2b1f97264..8f4a091fb11 100644 --- a/src/devices/cpu/arm7/ap2010cpu.cpp +++ b/src/devices/cpu/arm7/ap2010cpu.cpp @@ -28,7 +28,7 @@ void ap2010cpu_device::add_hotspot(offs_t pc) void ap2010cpu_device::execute_run() { - for (size_t i = 0; i < ARM7_MAX_HOTSPOTS; i++) { + for (size_t i = 0; i < MAX_HOTSPOTS; i++) { if (m_hotspot[i] == 0) { break; } diff --git a/src/devices/cpu/arm7/ap2010cpu.h b/src/devices/cpu/arm7/ap2010cpu.h index 3cf0a3c53dd..36664a260fe 100644 --- a/src/devices/cpu/arm7/ap2010cpu.h +++ b/src/devices/cpu/arm7/ap2010cpu.h @@ -16,6 +16,8 @@ class ap2010cpu_device : public arm7_cpu_device { public: + static inline constexpr unsigned MAX_HOTSPOTS = 16; + ap2010cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); void add_hotspot(offs_t pc); @@ -26,7 +28,7 @@ protected: private: uint32_t m_hotspot_select = 0; - uint32_t m_hotspot[ARM7_MAX_HOTSPOTS]; + uint32_t m_hotspot[MAX_HOTSPOTS]; }; // device type definition diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 46ffa46e41a..89c89afada5 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -1151,8 +1151,6 @@ void arm7_cpu_device::device_reset() SwitchMode(eARM7_MODE_SVC); m_r[eR15] = 0 | m_vectorbase; - m_impstate.cache_dirty = true; - for (auto &entry : m_dtlb_entries) { entry.valid = false; @@ -2411,5 +2409,3 @@ uint8_t arm7_cpu_device::arm7_cpu_read8(uint32_t addr) // Handle through normal 8 bit handler (for 32 bit cpu) return m_program->read_byte(addr); } - -#include "arm7drc.hxx" diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index 73cf8f44109..15931cadb44 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -25,24 +25,6 @@ #include "arm7dasm.h" -#include "cpu/drcfe.h" -#include "cpu/drcuml.h" -#include "cpu/drcumlsh.h" - - -#define ARM7_MAX_FASTRAM 4 -#define ARM7_MAX_HOTSPOTS 16 - -/*************************************************************************** - COMPILER-SPECIFIC OPTIONS -***************************************************************************/ - -#define ARM7DRC_STRICT_VERIFY 0x0001 /* verify all instructions */ -#define ARM7DRC_FLUSH_PC 0x0008 /* flush the PC value before each memory access */ - -#define ARM7DRC_COMPATIBLE_OPTIONS (ARM7DRC_STRICT_VERIFY | ARM7DRC_FLUSH_PC) -#define ARM7DRC_FASTEST_OPTIONS (0) - /**************************************************************************************************** * PUBLIC FUNCTIONS ***************************************************************************************************/ @@ -372,226 +354,8 @@ protected: typedef void ( arm7_cpu_device::*arm7ops_ophandler )(uint32_t); static const arm7ops_ophandler ops_handler[0x20]; - // - // DRC - // - - /* fast RAM info */ - struct fast_ram_info - { - offs_t start = 0; /* start of the RAM block */ - offs_t end = 0; /* end of the RAM block */ - bool readonly = false; /* true if read-only */ - void * base = nullptr; /* base in memory where the RAM lives */ - }; - - struct hotspot_info - { - uint32_t pc = 0; - uint32_t opcode = 0; - uint32_t cycles = 0; - }; - - /* internal compiler state */ - struct compiler_state - { - compiler_state &operator=(compiler_state const &) = delete; - - uint32_t cycles = 0; /* accumulated cycles */ - uint8_t checkints = 0; /* need to check interrupts before next instruction */ - uint8_t checksoftints = 0; /* need to check software interrupts before next instruction */ - uml::code_label labelnum; /* index for local labels */ - }; - - /* ARM7 registers */ - struct arm7imp_state - { - /* core state */ - std::unique_ptr<drc_cache> cache; /* pointer to the DRC code cache */ - std::unique_ptr<drcuml_state> drcuml; /* DRC UML generator state */ - //arm7_frontend * drcfe = nullptr; /* pointer to the DRC front-end state */ - uint32_t drcoptions = 0; /* configurable DRC options */ - - /* internal stuff */ - uint8_t cache_dirty = 0; /* true if we need to flush the cache */ - uint32_t jmpdest = 0; /* destination jump target */ - - /* parameters for subroutines */ - uint64_t numcycles = 0; /* return value from gettotalcycles */ - uint32_t mode = 0; /* current global mode */ - const char * format = nullptr; /* format string for print_debug */ - uint32_t arg0 = 0; /* print_debug argument 1 */ - uint32_t arg1 = 0; /* print_debug argument 2 */ - - /* register mappings */ - uml::parameter regmap[/*NUM_REGS*/37]; /* parameter to register mappings for all 16 integer registers */ - - /* subroutines */ - uml::code_handle * entry = nullptr; /* entry point */ - uml::code_handle * nocode = nullptr; /* nocode exception handler */ - uml::code_handle * out_of_cycles = nullptr; /* out of cycles exception handler */ - uml::code_handle * tlb_translate = nullptr; /* tlb translation handler */ - uml::code_handle * detect_fault = nullptr; /* tlb fault detection handler */ - uml::code_handle * check_irq = nullptr; /* irq check handler */ - uml::code_handle * read8 = nullptr; /* read byte */ - uml::code_handle * write8 = nullptr; /* write byte */ - uml::code_handle * read16 = nullptr; /* read half */ - uml::code_handle * write16 = nullptr; /* write half */ - uml::code_handle * read32 = nullptr; /* read word */ - uml::code_handle * write32 = nullptr; /* write word */ - - /* fast RAM */ - uint32_t fastram_select = 0; - fast_ram_info fastram[ARM7_MAX_FASTRAM]; - - /* hotspots */ - uint32_t hotspot_select = 0; - hotspot_info hotspot[ARM7_MAX_HOTSPOTS]; - } m_impstate; - - typedef void ( arm7_cpu_device::*arm7thumb_drcophandler)(drcuml_block &, compiler_state &, const opcode_desc *); - static const arm7thumb_drcophandler drcthumb_handler[0x40*0x10]; - - void drctg00_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Shift left */ - void drctg00_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Shift right */ - void drctg01_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg01_10(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg01_11(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* SUB Rd, Rs, Rn */ - void drctg01_12(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD Rd, Rs, #imm */ - void drctg01_13(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* SUB Rd, Rs, #imm */ - void drctg02_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg02_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg03_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD Rd, #Offset8 */ - void drctg03_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* SUB Rd, #Offset8 */ - void drctg04_00_00(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* AND Rd, Rs */ - void drctg04_00_01(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* EOR Rd, Rs */ - void drctg04_00_02(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LSL Rd, Rs */ - void drctg04_00_03(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LSR Rd, Rs */ - void drctg04_00_04(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ASR Rd, Rs */ - void drctg04_00_05(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADC Rd, Rs */ - void drctg04_00_06(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* SBC Rd, Rs */ - void drctg04_00_07(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ROR Rd, Rs */ - void drctg04_00_08(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* TST Rd, Rs */ - void drctg04_00_09(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* NEG Rd, Rs */ - void drctg04_00_0a(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* CMP Rd, Rs */ - void drctg04_00_0b(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* CMN Rd, Rs - check flags, add dasm */ - void drctg04_00_0c(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ORR Rd, Rs */ - void drctg04_00_0d(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* MUL Rd, Rs */ - void drctg04_00_0e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* BIC Rd, Rs */ - void drctg04_00_0f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* MVN Rd, Rs */ - void drctg04_01_00(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg04_01_01(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD Rd, HRs */ - void drctg04_01_02(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD HRd, Rs */ - void drctg04_01_03(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Add HRd, HRs */ - void drctg04_01_10(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* CMP Rd, Rs */ - void drctg04_01_11(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* CMP Rd, Hs */ - void drctg04_01_12(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* CMP Hd, Rs */ - void drctg04_01_13(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* CMP Hd, Hs */ - void drctg04_01_20(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* MOV Rd, Rs (undefined) */ - void drctg04_01_21(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* MOV Rd, Hs */ - void drctg04_01_22(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* MOV Hd, Rs */ - void drctg04_01_23(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* MOV Hd, Hs */ - void drctg04_01_30(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg04_01_31(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg04_01_32(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg04_01_33(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg04_0203(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg05_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* STR Rd, [Rn, Rm] */ - void drctg05_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* STRH Rd, [Rn, Rm] */ - void drctg05_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* STRB Rd, [Rn, Rm] */ - void drctg05_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LDSB Rd, [Rn, Rm] todo, add dasm */ - void drctg05_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LDR Rd, [Rn, Rm] */ - void drctg05_5(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LDRH Rd, [Rn, Rm] */ - void drctg05_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LDRB Rd, [Rn, Rm] */ - void drctg05_7(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* LDSH Rd, [Rn, Rm] */ - void drctg06_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Store */ - void drctg06_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Load */ - void drctg07_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Store */ - void drctg07_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Load */ - void drctg08_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Store */ - void drctg08_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Load */ - void drctg09_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Store */ - void drctg09_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Load */ - void drctg0a_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD Rd, PC, #nn */ - void drctg0a_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD Rd, SP, #nn */ - void drctg0b_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* ADD SP, #imm */ - void drctg0b_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* PUSH {Rlist} */ - void drctg0b_5(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* PUSH {Rlist}{LR} */ - void drctg0b_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_7(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_8(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_9(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_a(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_b(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_c(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* POP {Rlist} */ - void drctg0b_d(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* POP {Rlist}{PC} */ - void drctg0b_e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0b_f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0c_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Store */ - void drctg0c_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* Load */ - void drctg0d_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_EQ: - void drctg0d_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_NE: - void drctg0d_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_CS: - void drctg0d_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_CC: - void drctg0d_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_MI: - void drctg0d_5(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_PL: - void drctg0d_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_VS: - void drctg0d_7(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_VC: - void drctg0d_8(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_HI: - void drctg0d_9(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_LS: - void drctg0d_a(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_GE: - void drctg0d_b(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_LT: - void drctg0d_c(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_GT: - void drctg0d_d(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_LE: - void drctg0d_e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // COND_AL: - void drctg0d_f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); // SWI (this is sort of a "hole" in the opcode encoding) - void drctg0e_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0e_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0f_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void drctg0f_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); /* BL */ - void update_reg_ptr(); const int* m_reg_group; - void load_fast_iregs(drcuml_block &block); - void save_fast_iregs(drcuml_block &block); - void arm7_drc_init(); - void arm7_drc_exit(); - void execute_run_drc(); - void arm7drc_set_options(uint32_t options); - void arm7drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base); - void arm7drc_add_hotspot(offs_t pc, uint32_t opcode, uint32_t cycles); - void code_flush_cache(); - void code_compile_block(uint8_t mode, offs_t pc); - void cfunc_get_cycles(); - void cfunc_unimplemented(); - void static_generate_entry_point(); - void static_generate_check_irq(); - void static_generate_nocode_handler(); - void static_generate_out_of_cycles(); - void static_generate_detect_fault(uml::code_handle **handleptr); - void static_generate_tlb_translate(uml::code_handle **handleptr); - void static_generate_memory_accessor(int size, bool istlb, bool iswrite, const char *name, uml::code_handle *&handleptr); - void generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param); - void generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); - void generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - void generate_delay_slot_and_branch(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t linkreg); - - typedef bool ( arm7_cpu_device::*drcarm7ops_ophandler)(drcuml_block &, compiler_state &, const opcode_desc *, uint32_t); - static const drcarm7ops_ophandler drcops_handler[0x10]; - - void saturate_qbit_overflow(drcuml_block &block); - bool drcarm7ops_0123(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool drcarm7ops_4567(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool drcarm7ops_89(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool drcarm7ops_ab(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool drcarm7ops_cd(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool drcarm7ops_e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool drcarm7ops_f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op); - bool generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); - }; diff --git a/src/devices/cpu/arm7/arm7drc.hxx b/src/devices/cpu/arm7/arm7drc.hxx deleted file mode 100644 index 9afdf5e7c88..00000000000 --- a/src/devices/cpu/arm7/arm7drc.hxx +++ /dev/null @@ -1,1812 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Steve Ellenoff,R. Belmont,Ryan Holtz -/***************************************************************************** - * - * arm7drc.hxx - * Portable CPU Emulator for 32-bit ARM v3/4/5/6 - * - * Copyright Steve Ellenoff - * Thumb, DSP, and MMU support and many bugfixes by R. Belmont and Ryan Holtz. - * Dyanmic Recompiler (DRC) / Just In Time Compiler (JIT) by Ryan Holtz. - * - * This work is based on: - * #1) 'Atmel Corporation ARM7TDMI (Thumb) Datasheet - January 1999' - * #2) Arm 2/3/6 emulator By Bryan McPhail (bmcphail@tendril.co.uk) and Phil Stroffolino (MAME CORE 0.76) - * - *****************************************************************************/ - -/****************************************************************************** - * Notes: - - ** This is a plain vanilla implementation of an ARM7 cpu which incorporates my ARM7 core. - It can be used as is, or used to demonstrate how to utilize the arm7 core to create a cpu - that uses the core, since there are numerous different mcu packages that incorporate an arm7 core. - - See the notes in the arm7core.c file itself regarding issues/limitations of the arm7 core. - ** -*****************************************************************************/ - - -/*************************************************************************** - DEBUGGING -***************************************************************************/ - -#define SINGLE_INSTRUCTION_MODE (0) - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -#include "arm7tdrc.hxx" - -/* map variables */ -#define MAPVAR_PC uml::M0 -#define MAPVAR_CYCLES uml::M1 - -/* size of the execution code cache */ -#define CACHE_SIZE (32 * 1024 * 1024) - -/* compilation boundaries -- how far back/forward does the analysis extend? */ -#define COMPILE_BACKWARDS_BYTES 128 -#define COMPILE_FORWARDS_BYTES 512 -#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4)) -#define COMPILE_MAX_SEQUENCE 64 - -/* exit codes */ -#define EXECUTE_OUT_OF_CYCLES 0 -#define EXECUTE_MISSING_CODE 1 -#define EXECUTE_UNMAPPED_CODE 2 -#define EXECUTE_RESET_CACHE 3 - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - epc - compute the exception PC from a - descriptor --------------------------------------------------*/ - -static inline uint32_t epc(const opcode_desc *desc) -{ - return desc->pc; -} - - -/*------------------------------------------------- - alloc_handle - allocate a handle if not - already allocated --------------------------------------------------*/ - -static inline void alloc_handle(drcuml_state &drcuml, uml::code_handle *&handleptr, const char *name) -{ - if (!handleptr) - handleptr = drcuml.handle_alloc(name); -} - - -/*------------------------------------------------- - load_fast_iregs - load any fast integer - registers --------------------------------------------------*/ - -void arm7_cpu_device::load_fast_iregs(drcuml_block &block) -{ - int regnum; - - for (regnum = 0; regnum < std::size(m_impstate.regmap); regnum++) - if (m_impstate.regmap[regnum].is_int_register()) - UML_DMOV(block, uml::ireg(m_impstate.regmap[regnum].ireg() - uml::REG_I0), uml::mem(&m_r[regnum])); -} - - -/*------------------------------------------------- - save_fast_iregs - save any fast integer - registers --------------------------------------------------*/ - -void arm7_cpu_device::save_fast_iregs(drcuml_block &block) -{ - int regnum; - - for (regnum = 0; regnum < std::size(m_impstate.regmap); regnum++) - if (m_impstate.regmap[regnum].is_int_register()) - UML_DMOV(block, uml::mem(&m_r[regnum]), uml::ireg(m_impstate.regmap[regnum].ireg() - uml::REG_I0)); -} - - - -/*************************************************************************** - CORE CALLBACKS -***************************************************************************/ - -/*------------------------------------------------- - arm7_init - initialize the processor --------------------------------------------------*/ - -void arm7_cpu_device::arm7_drc_init() -{ - drcbe_info beinfo; - uint32_t flags = 0; - - /* allocate enough space for the cache and the core */ - - /* allocate the implementation-specific state from the full cache */ - m_impstate = arm7imp_state(); - try { m_impstate.cache = std::make_unique<drc_cache>(CACHE_SIZE); } - catch (std::bad_alloc const &) { throw emu_fatalerror("Unable to allocate cache of size %d\n", (uint32_t)(CACHE_SIZE)); } - - /* initialize the UML generator */ - m_impstate.drcuml = std::make_unique<drcuml_state>(*this, *m_impstate.cache, flags, 1, 32, 1); - - /* add symbols for our stuff */ - m_impstate.drcuml->symbol_add(&m_icount, sizeof(m_icount), "icount"); - for (int regnum = 0; regnum < 37; regnum++) - { - char buf[10]; - sprintf(buf, "r%d", regnum); - m_impstate.drcuml->symbol_add(&m_r[regnum], sizeof(m_r[regnum]), buf); - } - m_impstate.drcuml->symbol_add(&m_impstate.mode, sizeof(m_impstate.mode), "mode"); - m_impstate.drcuml->symbol_add(&m_impstate.arg0, sizeof(m_impstate.arg0), "arg0"); - m_impstate.drcuml->symbol_add(&m_impstate.arg1, sizeof(m_impstate.arg1), "arg1"); - m_impstate.drcuml->symbol_add(&m_impstate.numcycles, sizeof(m_impstate.numcycles), "numcycles"); - //m_impstate.drcuml->symbol_add(&m_impstate.fpmode, sizeof(m_impstate.fpmode), "fpmode"); // TODO - - /* initialize the front-end helper */ - //m_impstate.drcfe = std::make_unique<arm7_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); - - /* allocate memory for cache-local state and initialize it */ - //memcpy(&m_impstate.fpmode, fpmode_source, sizeof(fpmode_source)); // TODO - - /* compute the register parameters */ - for (int regnum = 0; regnum < 37; regnum++) - { - m_impstate.regmap[regnum] = (regnum == 0) ? uml::parameter(0) : uml::parameter::make_memory(&m_r[regnum]); - } - - /* if we have registers to spare, assign r2, r3, r4 to leftovers */ - //if (!DISABLE_FAST_REGISTERS) // TODO - { - m_impstate.drcuml->get_backend_info(beinfo); - if (beinfo.direct_iregs > 4) - { // PC - m_impstate.regmap[eR15] = uml::I4; - } - if (beinfo.direct_iregs > 5) - { // Status - m_impstate.regmap[eCPSR] = uml::I5; - } - if (beinfo.direct_iregs > 6) - { // SP - m_impstate.regmap[eR13] = uml::I6; - } - } - - /* mark the cache dirty so it is updated on next execute */ - m_impstate.cache_dirty = true; -} - - -/*------------------------------------------------- - arm7_execute - execute the CPU for the - specified number of cycles --------------------------------------------------*/ - -void arm7_cpu_device::execute_run_drc() -{ - drcuml_state &drcuml = *m_impstate.drcuml; - int execute_result; - - /* reset the cache if dirty */ - if (m_impstate.cache_dirty) - code_flush_cache(); - m_impstate.cache_dirty = false; - - /* execute */ - do - { - /* run as much as we can */ - execute_result = drcuml.execute(*m_impstate.entry); - - /* if we need to recompile, do it */ - if (execute_result == EXECUTE_MISSING_CODE) - code_compile_block(m_impstate.mode, m_r[eR15]); - else if (execute_result == EXECUTE_UNMAPPED_CODE) - fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_r[eR15]); - else if (execute_result == EXECUTE_RESET_CACHE) - code_flush_cache(); - - } while (execute_result != EXECUTE_OUT_OF_CYCLES); -} - -/*------------------------------------------------- - arm7_exit - cleanup from execution --------------------------------------------------*/ - -void arm7_cpu_device::arm7_drc_exit() -{ - /* clean up the DRC */ - //m_impstate.drcfe.reset(); - m_impstate.drcuml.reset(); - m_impstate.cache.reset(); -} - - -/*------------------------------------------------- - arm7drc_set_options - configure DRC options --------------------------------------------------*/ - -void arm7_cpu_device::arm7drc_set_options(uint32_t options) -{ - m_impstate.drcoptions = options; -} - - -/*------------------------------------------------- - arm7drc_add_fastram - add a new fastram - region --------------------------------------------------*/ - -void arm7_cpu_device::arm7drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base) -{ - if (m_impstate.fastram_select < std::size(m_impstate.fastram)) - { - m_impstate.fastram[m_impstate.fastram_select].start = start; - m_impstate.fastram[m_impstate.fastram_select].end = end; - m_impstate.fastram[m_impstate.fastram_select].readonly = readonly; - m_impstate.fastram[m_impstate.fastram_select].base = base; - m_impstate.fastram_select++; - } -} - - -/*------------------------------------------------- - arm7drc_add_hotspot - add a new hotspot --------------------------------------------------*/ - -void arm7_cpu_device::arm7drc_add_hotspot(offs_t pc, uint32_t opcode, uint32_t cycles) -{ - if (m_impstate.hotspot_select < std::size(m_impstate.hotspot)) - { - m_impstate.hotspot[m_impstate.hotspot_select].pc = pc; - m_impstate.hotspot[m_impstate.hotspot_select].opcode = opcode; - m_impstate.hotspot[m_impstate.hotspot_select].cycles = cycles; - m_impstate.hotspot_select++; - } -} - - - -/*************************************************************************** - CACHE MANAGEMENT -***************************************************************************/ - -/*------------------------------------------------- - code_flush_cache - flush the cache and - regenerate static code --------------------------------------------------*/ - -void arm7_cpu_device::code_flush_cache() -{ - /* empty the transient cache contents */ - m_impstate.drcuml->reset(); - - try - { - /* generate the entry point and out-of-cycles handlers */ - static_generate_entry_point(); - static_generate_nocode_handler(); - static_generate_out_of_cycles(); - static_generate_tlb_translate(nullptr); // TODO FIXME - static_generate_detect_fault(nullptr); // TODO FIXME - //static_generate_tlb_mismatch(); - - /* add subroutines for memory accesses */ - static_generate_memory_accessor(1, false, false, "read8", m_impstate.read8); - static_generate_memory_accessor(1, true, false, "write8", m_impstate.write8); - static_generate_memory_accessor(2, false, false, "read16", m_impstate.read16); - static_generate_memory_accessor(2, true, false, "write16", m_impstate.write16); - static_generate_memory_accessor(4, false, false, "read32", m_impstate.read32); - static_generate_memory_accessor(4, true, false, "write32", m_impstate.write32); - } - catch (drcuml_block::abort_compilation &) - { - fatalerror("Unrecoverable error generating static code\n"); - } -} - - -/*------------------------------------------------- - code_compile_block - compile a block of the - given mode at the specified pc --------------------------------------------------*/ - -void arm7_cpu_device::code_compile_block(uint8_t mode, offs_t pc) -{ - drcuml_state &drcuml = *m_impstate.drcuml; - compiler_state compiler = { 0 }; - const opcode_desc *seqlast; - bool override = false; - - auto profile = g_profiler.start(PROFILER_DRC_COMPILE); - - /* get a description of this sequence */ - // TODO FIXME - const opcode_desc *desclist = nullptr; //m_impstate.drcfe->describe_code(pc); // TODO -// if (drcuml.logging() || drcuml.logging_native()) -// log_opcode_desc(drcuml, desclist, 0); - - /* if we get an error back, flush the cache and try again */ - bool succeeded = false; - while (!succeeded) - { - try - { - /* start the block */ - drcuml_block &block(drcuml.begin_block(4096)); - - /* loop until we get through all instruction sequences */ - for (const opcode_desc *seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next()) - { - const opcode_desc *curdesc; - uint32_t nextpc; - - /* add a code log entry */ - if (drcuml.logging()) - block.append_comment("-------------------------"); // comment - - /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) - break; - assert(seqlast != nullptr); - - /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ - if (override || !drcuml.hash_exists(mode, seqhead->pc)) - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - - /* if we already have a hash, and this is the first sequence, assume that we */ - /* are recompiling due to being out of sync and allow future overrides */ - else if (seqhead == desclist) - { - override = true; - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - } - - /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ - else - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - UML_HASHJMP(block, 0, seqhead->pc, *m_impstate.nocode); - // hashjmp <mode>,seqhead->pc,nocode - continue; - } - - /* validate this code block if we're not pointing into ROM */ - if (m_program->get_write_ptr(seqhead->physpc) != nullptr) - generate_checksum_block(block, compiler, seqhead, seqlast); - - /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - - /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) - generate_sequence_instruction(block, compiler, curdesc); - - /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) - nextpc = pc; - - /* otherwise we just go to the next instruction */ - else - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; - - /* count off cycles and go there */ - generate_update_cycles(block, compiler, nextpc); // <subtract cycles> - - /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ - /*if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES) - UML_HASHJMP(block, uml::mem(&m_impstate.mode), nextpc, *m_impstate.nocode); - // hashjmp <mode>,nextpc,nocode - else*/ if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc) - UML_HASHJMP(block, m_impstate.mode, nextpc, *m_impstate.nocode); - // hashjmp <mode>,nextpc,nocode - } - - /* end the sequence */ - block.end(); - succeeded = true; - } - catch (drcuml_block::abort_compilation &) - { - code_flush_cache(); - } - } -} - - -/*************************************************************************** - C FUNCTION CALLBACKS -***************************************************************************/ - -/*------------------------------------------------- - cfunc_get_cycles - compute the total number - of cycles executed so far --------------------------------------------------*/ - -void arm7_cpu_device::cfunc_get_cycles() -{ - m_impstate.numcycles = total_cycles(); -} - - -/*------------------------------------------------- - cfunc_unimplemented - handler for - unimplemented opcdes --------------------------------------------------*/ - -void arm7_cpu_device::cfunc_unimplemented() -{ - uint32_t opcode = m_impstate.arg0; - fatalerror("PC=%08X: Unimplemented op %08X\n", m_r[eR15], opcode); -} - - -/*************************************************************************** - STATIC CODEGEN -***************************************************************************/ - -/*------------------------------------------------- - static_generate_entry_point - generate a - static entry point --------------------------------------------------*/ - -void arm7_cpu_device::static_generate_entry_point() -{ - drcuml_state &drcuml = *m_impstate.drcuml; - - drcuml_block &block(drcuml.begin_block(110)); - - /* forward references */ - //alloc_handle(drcuml, &m_impstate.exception_norecover[EXCEPTION_INTERRUPT], "interrupt_norecover"); - alloc_handle(drcuml, m_impstate.nocode, "nocode"); - alloc_handle(drcuml, m_impstate.detect_fault, "detect_fault"); - alloc_handle(drcuml, m_impstate.tlb_translate, "tlb_translate"); - - alloc_handle(drcuml, m_impstate.entry, "entry"); - UML_HANDLE(block, *m_impstate.entry); // handle entry - - /* load fast integer registers */ - load_fast_iregs(block); - - UML_CALLH(block, *m_impstate.check_irq); - - /* generate a hash jump via the current mode and PC */ - UML_HASHJMP(block, 0, uml::mem(&m_pc), *m_impstate.nocode); // hashjmp 0,<pc>,nocode - block.end(); -} - - -/*------------------------------------------------- - static_generate_check_irq - generate a handler - to check IRQs --------------------------------------------------*/ - -void arm7_cpu_device::static_generate_check_irq() -{ - drcuml_state &drcuml = *m_impstate.drcuml; - uml::code_label noirq; - int nodabt = 0; - int nopabt = 0; - int irqadjust = 0; - int nofiq = 0; - int irq32 = 0; - int swi32 = 0; - int done = 0; - int label = 1; - - /* begin generating */ - drcuml_block &block(drcuml.begin_block(120)); - - /* generate a hash jump via the current mode and PC */ - alloc_handle(drcuml, m_impstate.check_irq, "check_irq"); - UML_HANDLE(block, *m_impstate.check_irq); // handle check_irq - /* Exception priorities: - - Reset - Data abort - FIRQ - IRQ - Prefetch abort - Undefined instruction - Software Interrupt - */ - - UML_ADD(block, uml::I0, uml::mem(&R15), 4); // add i0, PC, 4 ;insn pc - - // Data Abort - UML_TEST(block, uml::mem(&m_pendingAbtD), 1); // test pendingAbtD, 1 - UML_JMPc(block, uml::COND_Z, nodabt = label++); // jmpz nodabt - - UML_ROLINS(block, uml::mem(&GET_CPSR), eARM7_MODE_ABT, 0, MODE_FLAG); // rolins CPSR, eARM7_MODE_ABT, 0, MODE_FLAG - UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0 - UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR - UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK - UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK - UML_MOV(block, uml::mem(&R15), 0x00000010); // mov PC, 0x10 (Data Abort vector address) - UML_MOV(block, uml::mem(&m_pendingAbtD), 0); // mov pendingAbtD, 0 - UML_JMP(block, irqadjust = label++); // jmp irqadjust - - UML_LABEL(block, nodabt); // nodabt: - - // FIQ - UML_TEST(block, uml::mem(&m_pendingFiq), 1); // test pendingFiq, 1 - UML_JMPc(block, uml::COND_Z, nofiq = label++); // jmpz nofiq - UML_TEST(block, uml::mem(&GET_CPSR), F_MASK); // test CPSR, F_MASK - UML_JMPc(block, uml::COND_Z, nofiq); // jmpz nofiq - - UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0 - UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR - UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK | F_MASK); // or CPSR, CPSR, I_MASK | F_MASK - UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK - UML_MOV(block, uml::mem(&R15), 0x0000001c); // mov PC, 0x1c (FIQ vector address) - UML_MOV(block, uml::mem(&m_pendingFiq), 0); // mov pendingFiq, 0 - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, nofiq); // nofiq: - - // IRQ - UML_TEST(block, uml::mem(&m_pendingIrq), 1); // test pendingIrq, 1 - UML_JMPc(block, uml::COND_Z, noirq = label++); // jmpz noirq - UML_TEST(block, uml::mem(&GET_CPSR), I_MASK); // test CPSR, I_MASK - UML_JMPc(block, uml::COND_Z, noirq); // jmpz noirq - - UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0 - UML_TEST(block, uml::mem(&GET_CPSR), SR_MODE32); // test CPSR, MODE32 - UML_JMPc(block, uml::COND_NZ, irq32 = label++); // jmpnz irq32 - UML_AND(block, uml::I1, uml::I0, 0xf4000000); // and i1, i0, 0xf4000000 - UML_OR(block, uml::mem(&R15), uml::I1, 0x0800001a); // or PC, i1, 0x0800001a - UML_AND(block, uml::I1, uml::mem(&GET_CPSR), 0x0fffff3f); // and i1, CPSR, 0x0fffff3f - UML_ROLAND(block, uml::I0, uml::mem(&R15), 32-20, 0x0000000c); // roland i0, R15, 32-20, 0x0000000c - UML_ROLINS(block, uml::I0, uml::mem(&R15), 0, 0xf0000000); // rolins i0, R15, 0, 0xf0000000 - UML_OR(block, uml::mem(&GET_CPSR), uml::I0, uml::I1); // or CPSR, i0, i1 - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, irq32); // irq32: - UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR - UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK - UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK - UML_MOV(block, uml::mem(&R15), 0x00000018); // mov PC, 0x18 (IRQ vector address) - - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, noirq); // noirq: - - // Prefetch Abort - UML_TEST(block, uml::mem(&m_pendingAbtP), 1); // test pendingAbtP, 1 - UML_JMPc(block, uml::COND_Z, nopabt = label++); // jmpz nopabt - - UML_ROLINS(block, uml::mem(&GET_CPSR), eARM7_MODE_ABT, 0, MODE_FLAG); // rolins CPSR, eARM7_MODE_ABT, 0, MODE_FLAG - UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0 - UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR - UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK - UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK - UML_MOV(block, uml::mem(&R15), 0x0000000c); // mov PC, 0x0c (Prefetch Abort vector address) - UML_MOV(block, uml::mem(&m_pendingAbtP), 0); // mov pendingAbtP, 0 - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, nopabt); // nopabt: - - // Undefined instruction - UML_TEST(block, uml::mem(&m_pendingUnd), 1); // test pendingUnd, 1 - UML_JMPc(block, uml::COND_Z, nopabt = label++); // jmpz nound - - UML_ROLINS(block, uml::mem(&GET_CPSR), eARM7_MODE_UND, 0, MODE_FLAG); // rolins CPSR, eARM7_MODE_UND, 0, MODE_FLAG - UML_MOV(block, uml::I1, (uint64_t)-4); // mov i1, -4 - UML_TEST(block, uml::mem(&GET_CPSR), T_MASK); // test CPSR, T_MASK - UML_MOVc(block, uml::COND_NZ, uml::I1, (uint64_t)-2); // movnz i1, -2 - UML_ADD(block, uml::mem(&GetRegister(14)), uml::I0, uml::I1); // add LR, i0, i1 - UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR - UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK - UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK - UML_MOV(block, uml::mem(&R15), 0x00000004); // mov PC, 0x0c (Undefined Insn vector address) - UML_MOV(block, uml::mem(&m_pendingUnd), 0); // mov pendingUnd, 0 - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, nopabt); // nopabt: - - // Software Interrupt - UML_TEST(block, uml::mem(&m_pendingSwi), 1); // test pendingSwi, 1 - UML_JMPc(block, uml::COND_Z, done = label++); // jmpz done - - UML_ROLINS(block, uml::mem(&GET_CPSR), eARM7_MODE_SVC, 0, MODE_FLAG); // rolins CPSR, eARM7_MODE_SVC, 0, MODE_FLAG - UML_MOV(block, uml::I1, (uint64_t)-4); // mov i1, -4 - UML_TEST(block, uml::mem(&GET_CPSR), T_MASK); // test CPSR, T_MASK - UML_MOVc(block, uml::COND_NZ, uml::I1, (uint64_t)-2); // movnz i1, -2 - UML_ADD(block, uml::mem(&GetRegister(14)), uml::I0, uml::I1); // add LR, i0, i1 - - UML_TEST(block, uml::mem(&GET_CPSR), SR_MODE32); // test CPSR, MODE32 - UML_JMPc(block, uml::COND_NZ, swi32 = label++); // jmpnz swi32 - UML_AND(block, uml::I1, uml::I0, 0xf4000000); // and i1, i0, 0xf4000000 - UML_OR(block, uml::mem(&R15), uml::I1, 0x0800001b); // or PC, i1, 0x0800001b - UML_AND(block, uml::I1, uml::mem(&GET_CPSR), 0x0fffff3f); // and i1, CPSR, 0x0fffff3f - UML_ROLAND(block, uml::I0, uml::mem(&R15), 32-20, 0x0000000c); // roland i0, R15, 32-20, 0x0000000c - UML_ROLINS(block, uml::I0, uml::mem(&R15), 0, 0xf0000000); // rolins i0, R15, 0, 0xf0000000 - UML_OR(block, uml::mem(&GET_CPSR), uml::I0, uml::I1); // or CPSR, i0, i1 - UML_MOV(block, uml::mem(&m_pendingSwi), 0); // mov pendingSwi, 0 - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, swi32); // irq32: - UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR - UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK - UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK - UML_MOV(block, uml::mem(&R15), 0x00000008); // mov PC, 0x08 (SWI vector address) - UML_MOV(block, uml::mem(&m_pendingSwi), 0); // mov pendingSwi, 0 - UML_JMP(block, irqadjust); // jmp irqadjust - - UML_LABEL(block, irqadjust); // irqadjust: - UML_MOV(block, uml::I1, 0); // mov i1, 0 - UML_TEST(block, uml::mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN | COPRO_CTRL_INTVEC_ADJUST); // test COPRO_CTRL, MMU_EN | INTVEC_ADJUST - UML_MOVc(block, uml::COND_NZ, uml::I1, 0xffff0000); // movnz i1, 0xffff0000 - UML_OR(block, uml::mem(&R15), uml::mem(&R15), uml::I1); // or PC, i1 - - UML_LABEL(block, done); // done: - - block.end(); -} - -/*------------------------------------------------- - static_generate_nocode_handler - generate an - exception handler for "out of code" --------------------------------------------------*/ - -void arm7_cpu_device::static_generate_nocode_handler() -{ - drcuml_state &drcuml = *m_impstate.drcuml; - - /* begin generating */ - drcuml_block &block(drcuml.begin_block(10)); - - /* generate a hash jump via the current mode and PC */ - alloc_handle(drcuml, m_impstate.nocode, "nocode"); - UML_HANDLE(block, *m_impstate.nocode); // handle nocode - UML_GETEXP(block, uml::I0); // getexp i0 - UML_MOV(block, uml::mem(&R15), uml::I0); // mov [pc],i0 - save_fast_iregs(block); - UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE - - block.end(); -} - - -/*------------------------------------------------- - static_generate_out_of_cycles - generate an - out of cycles exception handler --------------------------------------------------*/ - -void arm7_cpu_device::static_generate_out_of_cycles() -{ - drcuml_state &drcuml = *m_impstate.drcuml; - - /* begin generating */ - drcuml_block &block(drcuml.begin_block(10)); - - /* generate a hash jump via the current mode and PC */ - alloc_handle(drcuml, m_impstate.out_of_cycles, "out_of_cycles"); - UML_HANDLE(block, *m_impstate.out_of_cycles); // handle out_of_cycles - UML_GETEXP(block, uml::I0); // getexp i0 - UML_MOV(block, uml::mem(&R15), uml::I0); // mov <pc>,i0 - save_fast_iregs(block); - UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES - - block.end(); -} - - -/*------------------------------------------------------------------ - static_generate_detect_fault -------------------------------------------------------------------*/ - -void arm7_cpu_device::static_generate_detect_fault(uml::code_handle **handleptr) -{ - /* on entry, flags are in I2, vaddr is in I3, desc_lvl1 is in I4, ap is in R5 */ - /* on exit, fault result is in I6 */ - drcuml_state &drcuml = *m_impstate.drcuml; - int donefault = 0; - int checkuser = 0; - int label = 1; - - /* begin generating */ - drcuml_block &block(drcuml.begin_block(1024)); - - /* add a global entry for this */ - alloc_handle(drcuml, m_impstate.detect_fault, "detect_fault"); - UML_HANDLE(block, *m_impstate.detect_fault); // handle detect_fault - - UML_ROLAND(block, uml::I6, uml::I4, 32-4, 0x0f<<1); // roland i6, i4, 32-4, 0xf<<1 - UML_ROLAND(block, uml::I6, uml::mem(&COPRO_DOMAIN_ACCESS_CONTROL), uml::I6, 3);// roland i6, COPRO_DOMAIN_ACCESS_CONTROL, i6, 3 - // if permission == 3, FAULT_NONE - UML_CMP(block, uml::I6, 3); // cmp i6, 3 - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_NONE); // move i6, FAULT_NONE - UML_JMPc(block, uml::COND_E, donefault = label++); // jmpe donefault - // if permission == 0 || permission == 2, FAULT_DOMAIN - UML_CMP(block, uml::I6, 1); // cmp i6, 1 - UML_MOVc(block, uml::COND_NE, uml::I6, FAULT_DOMAIN); // movne i6, FAULT_DOMAIN - UML_JMPc(block, uml::COND_NE, donefault); // jmpne donefault - - // if permission == 1 - UML_CMP(block, uml::I5, 3); // cmp i5, 3 - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_NONE); // move i6, FAULT_NONE - UML_JMPc(block, uml::COND_E, donefault); // jmpe donefault - UML_CMP(block, uml::I5, 0); // cmp i5, 1 - UML_JMPc(block, uml::COND_NE, checkuser = label++); // jmpne checkuser - UML_ROLAND(block, uml::I6, uml::mem(&COPRO_CTRL), // roland i6, COPRO_CTRL, 32 - COPRO_CTRL_SYSTEM_SHIFT, - 32 - COPRO_CTRL_SYSTEM_SHIFT, // COPRO_CTRL_SYSTEM | COPRO_CTRL_ROM - COPRO_CTRL_SYSTEM | COPRO_CTRL_ROM); - // if s == 0 && r == 0, FAULT_PERMISSION - UML_CMP(block, uml::I6, 0); // cmp i6, 0 - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_PERMISSION); // move i6, FAULT_PERMISSION - UML_JMPc(block, uml::COND_E, donefault); // jmpe donefault - // if s == 1 && r == 1, FAULT_PERMISSION - UML_CMP(block, uml::I6, 3); // cmp i6, 3 - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_PERMISSION); // move i6, FAULT_PERMISSION - UML_JMPc(block, uml::COND_E, donefault); // jmpe donefault - // if flags & TLB_WRITE, FAULT_PERMISSION - UML_TEST(block, uml::I2, ARM7_TLB_WRITE); // test i2, ARM7_TLB_WRITE - UML_MOVc(block, uml::COND_NZ, uml::I6, FAULT_PERMISSION); // move i6, FAULT_PERMISSION - UML_JMPc(block, uml::COND_NZ, donefault); // jmpe donefault - // if r == 1 && s == 0, FAULT_NONE - UML_CMP(block, uml::I6, 2); // cmp i6, 2 - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_NONE); // move i6, FAULT_NONE - UML_JMPc(block, uml::COND_E, donefault); // jmpe donefault - UML_AND(block, uml::I6, uml::mem(&GET_CPSR), MODE_FLAG); // and i6, GET_CPSR, MODE_FLAG - UML_CMP(block, uml::I6, eARM7_MODE_USER); // cmp i6, eARM7_MODE_USER - // if r == 0 && s == 1 && usermode, FAULT_PERMISSION - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_PERMISSION); // move i6, FAULT_PERMISSION - UML_MOVc(block, uml::COND_NE, uml::I6, FAULT_NONE); // movne i6, FAULT_NONE - UML_JMP(block, donefault); // jmp donefault - - UML_LABEL(block, checkuser); // checkuser: - // if !write, FAULT_NONE - UML_TEST(block, uml::I2, ARM7_TLB_WRITE); // test i2, ARM7_TLB_WRITE - UML_MOVc(block, uml::COND_Z, uml::I6, FAULT_NONE); // movz i6, FAULT_NONE - UML_JMPc(block, uml::COND_Z, donefault); // jmp donefault - UML_AND(block, uml::I6, uml::mem(&GET_CPSR), MODE_FLAG); // and i6, GET_CPSR, MODE_FLAG - UML_CMP(block, uml::I6, eARM7_MODE_USER); // cmp i6, eARM7_MODE_USER - UML_MOVc(block, uml::COND_E, uml::I6, FAULT_PERMISSION); // move i6, FAULT_PERMISSION - UML_MOVc(block, uml::COND_NE, uml::I6, FAULT_NONE); // move i6, FAULT_NONE - - UML_LABEL(block, donefault); // donefault: - UML_RET(block); // ret -} - -/*------------------------------------------------------------------ - static_generate_tlb_translate -------------------------------------------------------------------*/ - -void arm7_cpu_device::static_generate_tlb_translate(uml::code_handle **handleptr) -{ - /* on entry, address is in I0 and flags are in I2 */ - /* on exit, translated address is in I0 and success/failure is in I2 */ - /* routine trashes I4-I7 */ - drcuml_state &drcuml = *m_impstate.drcuml; - uml::code_label smallfault; - uml::code_label smallprefetch; - int nopid = 0; - int nounmapped = 0; - int nounmapped2 = 0; - int nocoarse = 0; - int nofine = 0; - int nosection = 0; - int nolargepage = 0; - int nosmallpage = 0; - int notinypage = 0; - int handlefault = 0; - int level2 = 0; - int prefetch = 0; - int prefetch2 = 0; - int label = 1; - - /* begin generating */ - drcuml_block &block(drcuml.begin_block(170)); - - alloc_handle(drcuml, m_impstate.tlb_translate, "tlb_translate"); - UML_HANDLE(block, *m_impstate.tlb_translate); // handle tlb_translate - - // I3: vaddr - UML_CMP(block, uml::I0, 32 * 1024 * 1024); // cmp i0, 32*1024*1024 - UML_JMPc(block, uml::COND_GE, nopid = label++); // jmpge nopid - UML_AND(block, uml::I3, uml::mem(&COPRO_FCSE_PID), 0xfe000000); // and i3, COPRO_FCSE_PID, 0xfe000000 - UML_ADD(block, uml::I3, uml::I3, uml::I0); // add i3, i3, i0 - - // I4: desc_lvl1 - UML_AND(block, uml::I4, uml::mem(&COPRO_TLB_BASE), COPRO_TLB_BASE_MASK); // and i4, COPRO_TLB_BASE, COPRO_TLB_BASE_MASK - UML_ROLINS(block, uml::I4, uml::I3, 32 - COPRO_TLB_VADDR_FLTI_MASK_SHIFT, // rolins i4, i3, 32-COPRO_TLB_VADDR_FLTI_MASK_SHIFT, - COPRO_TLB_VADDR_FLTI_MASK); // COPRO_TLB_VADDR_FLTI_MASK - UML_READ(block, uml::I4, uml::I4, uml::SIZE_DWORD, uml::SPACE_PROGRAM); // read32 i4, i4, PROGRAM - - // I7: desc_lvl1 & 3 - UML_AND(block, uml::I7, uml::I4, 3); // and i7, i4, 3 - - UML_CMP(block, uml::I7, COPRO_TLB_UNMAPPED); // cmp i7, COPRO_TLB_UNMAPPED - UML_JMPc(block, uml::COND_NE, nounmapped = label++); // jmpne nounmapped - - // TLB Unmapped - UML_TEST(block, uml::I2, ARM7_TLB_ABORT_D); // test i2, ARM7_TLB_ABORT_D - UML_MOVc(block, uml::COND_E, uml::mem(&COPRO_FAULT_STATUS_D), (5 << 0)); // move COPRO_FAULT_STATUS_D, (5 << 0) - UML_MOVc(block, uml::COND_E, uml::mem(&COPRO_FAULT_ADDRESS), uml::I3); // move COPRO_FAULT_ADDRESS, i3 - UML_MOVc(block, uml::COND_E, uml::mem(&m_pendingAbtD), 1); // move pendingAbtD, 1 - UML_MOVc(block, uml::COND_E, uml::I2, 0); // move i2, 0 - UML_RETc(block, uml::COND_E); // rete - - UML_TEST(block, uml::I2, ARM7_TLB_ABORT_P); // test i2, ARM7_TLB_ABORT_P - UML_MOVc(block, uml::COND_E, uml::mem(&m_pendingAbtP), 1); // move pendingAbtP, 1 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, nounmapped); // nounmapped: - UML_CMP(block, uml::I7, COPRO_TLB_COARSE_TABLE); // cmp i7, COPRO_TLB_COARSE_TABLE - UML_JMPc(block, uml::COND_NE, nocoarse = label++); // jmpne nocoarse - - UML_ROLAND(block, uml::I5, uml::I4, 32-4, 0x0f<<1); // roland i5, i4, 32-4, 0xf<<1 - UML_ROLAND(block, uml::I5, uml::mem(&COPRO_DOMAIN_ACCESS_CONTROL), uml::I5, 3);// roland i5, COPRO_DOMAIN_ACCESS_CONTROL, i5, 3 - UML_CMP(block, uml::I5, 1); // cmp i5, 1 - UML_JMPc(block, uml::COND_E, level2 = label++); // jmpe level2 - UML_CMP(block, uml::I5, 3); // cmp i5, 3 - UML_JMPc(block, uml::COND_NE, nofine = label++); // jmpne nofine - UML_LABEL(block, level2); // level2: - - // I7: desc_level2 - UML_AND(block, uml::I7, uml::I4, COPRO_TLB_CFLD_ADDR_MASK); // and i7, i4, COPRO_TLB_CFLD_ADDR_MASK - UML_ROLINS(block, uml::I7, uml::I3, 32 - COPRO_TLB_VADDR_CSLTI_MASK_SHIFT,// rolins i7, i3, 32 - COPRO_TLB_VADDR_CSLTI_MASK_SHIFT - COPRO_TLB_VADDR_CSLTI_MASK); // COPRO_TLB_VADDR_CSLTI_MASK - UML_READ(block, uml::I7, uml::I7, uml::SIZE_DWORD, uml::SPACE_PROGRAM); // read32 i7, i7, PROGRAM - UML_JMP(block, nofine); // jmp nofine - - UML_LABEL(block, nocoarse); // nocoarse: - UML_CMP(block, uml::I7, COPRO_TLB_SECTION_TABLE); // cmp i7, COPRO_TLB_SECTION_TABLE - UML_JMPc(block, uml::COND_NE, nosection = label++); // jmpne nosection - - UML_ROLAND(block, uml::I5, uml::I4, 32-10, 3); // roland i7, i4, 32-10, 3 - // result in I6 - UML_CALLH(block, *m_impstate.detect_fault); // callh detect_fault - UML_CMP(block, uml::I6, FAULT_NONE); // cmp i6, FAULT_NONE - UML_JMPc(block, uml::COND_NE, handlefault = label++); // jmpne handlefault - - // no fault, return translated address - UML_AND(block, uml::I0, uml::I3, ~COPRO_TLB_SECTION_PAGE_MASK); // and i0, i3, ~COPRO_TLB_SECTION_PAGE_MASK - UML_ROLINS(block, uml::I0, uml::I4, 0, COPRO_TLB_SECTION_PAGE_MASK); // rolins i0, i4, COPRO_TLB_SECTION_PAGE_MASK - UML_MOV(block, uml::I2, 1); // mov i2, 1 - UML_RET(block); // ret - - UML_LABEL(block, handlefault); // handlefault: - UML_TEST(block, uml::I2, ARM7_TLB_ABORT_D); // test i2, ARM7_TLB_ABORT_D - UML_JMPc(block, uml::COND_Z, prefetch = label++); // jmpz prefetch - UML_MOV(block, uml::mem(&COPRO_FAULT_ADDRESS), uml::I3); // mov COPRO_FAULT_ADDRESS, i3 - UML_MOV(block, uml::mem(&m_pendingAbtD), 1); // mov m_pendingAbtD, 1 - UML_ROLAND(block, uml::I5, uml::I4, 31, 0xf0); // roland i5, i4, 31, 0xf0 - UML_CMP(block, uml::I6, FAULT_DOMAIN); // cmp i6, FAULT_DOMAIN - UML_MOVc(block, uml::COND_E, uml::I6, 9 << 0); // move i6, 9 << 0 - UML_MOVc(block, uml::COND_NE, uml::I6, 13 << 0); // movne i6, 13 << 0 - UML_OR(block, uml::mem(&COPRO_FAULT_STATUS_D), uml::I5, uml::I6); // or COPRO_FAULT_STATUS_D, i5, i6 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, prefetch); // prefetch: - UML_MOV(block, uml::mem(&m_pendingAbtP), 1); // mov m_pendingAbtP, 1 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, nosection); // nosection: - UML_CMP(block, uml::I7, COPRO_TLB_FINE_TABLE); // cmp i7, COPRO_TLB_FINE_TABLE - UML_JMPc(block, uml::COND_NE, nofine); // jmpne nofine - - // Not yet implemented - UML_MOV(block, uml::I2, 1); // mov i2, 1 - UML_RET(block); // ret - - UML_LABEL(block, nofine); // nofine: - - // I7: desc_lvl2 - UML_AND(block, uml::I6, uml::I7, 3); // and i6, i7, 3 - UML_CMP(block, uml::I6, COPRO_TLB_UNMAPPED); // cmp i6, COPRO_TLB_UNMAPPED - UML_JMPc(block, uml::COND_NE, nounmapped2 = label++); // jmpne nounmapped2 - - UML_TEST(block, uml::I2, ARM7_TLB_ABORT_D); // test i2, ARM7_TLB_ABORT_D - UML_JMPc(block, uml::COND_Z, prefetch2 = label++); // jmpz prefetch2 - UML_MOV(block, uml::mem(&COPRO_FAULT_ADDRESS), uml::I3); // mov COPRO_FAULT_ADDRESS, i3 - UML_MOV(block, uml::mem(&m_pendingAbtD), 1); // mov m_pendingAbtD, 1 - UML_ROLAND(block, uml::I5, uml::I4, 31, 0xf0); // roland i5, i4, 31, 0xf0 - UML_OR(block, uml::I5, uml::I5, 7 << 0); // or i5, i5, 7 << 0 - UML_OR(block, uml::mem(&COPRO_FAULT_STATUS_D), uml::I5, uml::I6); // or COPRO_FAULT_STATUS_D, i5, i6 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, prefetch2); // prefetch2: - UML_MOV(block, uml::mem(&m_pendingAbtP), 1); // mov m_pendingAbtP, 1 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, nounmapped2); // nounmapped2: - UML_CMP(block, uml::I6, COPRO_TLB_LARGE_PAGE); // cmp i6, COPRO_TLB_LARGE_PAGE - UML_JMPc(block, uml::COND_NE, nolargepage = label++); // jmpne nolargepage - - UML_AND(block, uml::I0, uml::I3, ~COPRO_TLB_LARGE_PAGE_MASK); // and i0, i3, ~COPRO_TLB_LARGE_PAGE_MASK - UML_ROLINS(block, uml::I0, uml::I7, 0, COPRO_TLB_LARGE_PAGE_MASK); // rolins i0, i7, 0, COPRO_TLB_LARGE_PAGE_MASK - UML_MOV(block, uml::I2, 1); // mov i2, 1 - UML_RET(block); // ret - - UML_LABEL(block, nolargepage); // nolargepage: - UML_CMP(block, uml::I6, COPRO_TLB_SMALL_PAGE); // cmp i6, COPRO_TLB_SMALL_PAGE - UML_JMPc(block, uml::COND_NE, nosmallpage = label++); // jmpne nosmallpage - - UML_ROLAND(block, uml::I5, uml::I3, 32-9, 3<<1); // roland i5, i3, 32-9, 3<<1 - UML_ROLAND(block, uml::I6, uml::I7, 32-4, 0xff); // roland i6, i7, 32-4, 0xff - UML_SHR(block, uml::I5, uml::I7, uml::I5); // shr i5, i7, i5 - UML_AND(block, uml::I5, uml::I5, 3); // and i5, i5, 3 - // result in I6 - UML_CALLH(block, *m_impstate.detect_fault); // callh detect_fault - - UML_CMP(block, uml::I6, FAULT_NONE); // cmp i6, FAULT_NONE - UML_JMPc(block, uml::COND_NE, smallfault = label++); // jmpne smallfault - UML_AND(block, uml::I0, uml::I7, COPRO_TLB_SMALL_PAGE_MASK); // and i0, i7, COPRO_TLB_SMALL_PAGE_MASK - UML_ROLINS(block, uml::I0, uml::I3, 0, ~COPRO_TLB_SMALL_PAGE_MASK); // rolins i0, i3, 0, ~COPRO_TLB_SMALL_PAGE_MASK - UML_MOV(block, uml::I2, 1); // mov i2, 1 - UML_RET(block); // ret - - UML_LABEL(block, smallfault); // smallfault: - UML_TEST(block, uml::I2, ARM7_TLB_ABORT_D); // test i2, ARM7_TLB_ABORT_D - UML_JMPc(block, uml::COND_NZ, smallprefetch = label++); // jmpnz smallprefetch - UML_MOV(block, uml::mem(&COPRO_FAULT_ADDRESS), uml::I3); // mov COPRO_FAULT_ADDRESS, i3 - UML_MOV(block, uml::mem(&m_pendingAbtD), 1); // mov pendingAbtD, 1 - UML_CMP(block, uml::I6, FAULT_DOMAIN); // cmp i6, FAULT_DOMAIN - UML_MOVc(block, uml::COND_E, uml::I5, 11 << 0); // move i5, 11 << 0 - UML_MOVc(block, uml::COND_NE, uml::I5, 15 << 0); // movne i5, 15 << 0 - UML_ROLINS(block, uml::I5, uml::I4, 31, 0xf0); // rolins i5, i4, 31, 0xf0 - UML_MOV(block, uml::mem(&COPRO_FAULT_STATUS_D), uml::I5); // mov COPRO_FAULT_STATUS_D, i5 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, smallprefetch); // smallprefetch: - UML_MOV(block, uml::mem(&m_pendingAbtP), 1); // mov pendingAbtP, 1 - UML_MOV(block, uml::I2, 0); // mov i2, 0 - UML_RET(block); // ret - - UML_LABEL(block, nosmallpage); // nosmallpage: - UML_CMP(block, uml::I6, COPRO_TLB_TINY_PAGE); // cmp i6, COPRO_TLB_TINY_PAGE - UML_JMPc(block, uml::COND_NE, notinypage = label++); // jmpne notinypage - - UML_AND(block, uml::I0, uml::I3, ~COPRO_TLB_TINY_PAGE_MASK); // and i0, i3, ~COPRO_TLB_TINY_PAGE_MASK - UML_ROLINS(block, uml::I0, uml::I7, 0, COPRO_TLB_TINY_PAGE_MASK); // rolins i0, i7, 0, COPRO_TLB_TINY_PAGE_MASK - UML_MOV(block, uml::I2, 1); // mov i2, 1 - UML_RET(block); // ret - - UML_LABEL(block, notinypage); // notinypage: - UML_MOV(block, uml::I0, uml::I3); // mov i0, i3 - UML_RET(block); // ret - - block.end(); -} - -/*------------------------------------------------------------------ - static_generate_memory_accessor -------------------------------------------------------------------*/ - -void arm7_cpu_device::static_generate_memory_accessor(int size, bool istlb, bool iswrite, const char *name, uml::code_handle *&handleptr) -{ - /* on entry, address is in I0; data for writes is in I1, fetch type in I2 */ - /* on exit, read result is in I0 */ - /* routine trashes I0-I3 */ - drcuml_state &drcuml = *m_impstate.drcuml; - //int tlbmiss = 0; - int label = 1; - - /* begin generating */ - drcuml_block &block(drcuml.begin_block(1024)); - - /* add a global entry for this */ - alloc_handle(drcuml, handleptr, name); - UML_HANDLE(block, *handleptr); // handle *handleptr - - if (istlb) - { - UML_TEST(block, uml::mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN - if (iswrite) - { - UML_MOVc(block, uml::COND_NZ, uml::I3, ARM7_TLB_WRITE); // movnz i3, ARM7_TLB_WRITE - } - else - { - UML_MOVc(block, uml::COND_NZ, uml::I3, ARM7_TLB_READ); // movnz i3, ARM7_TLB_READ - } - UML_OR(block, uml::I2, uml::I2, uml::I3); // or i2, i2, i3 - UML_CALLHc(block, uml::COND_NZ, *m_impstate.tlb_translate); // callhnz tlb_translate - } - - /* general case: assume paging and perform a translation */ - if (!debugger_enabled()) - { - for (int ramnum = 0; ramnum < ARM7_MAX_FASTRAM; ramnum++) - { - if (m_impstate.fastram[ramnum].base != nullptr && (!iswrite || !m_impstate.fastram[ramnum].readonly)) - { - void *fastbase = (uint8_t *)m_impstate.fastram[ramnum].base - m_impstate.fastram[ramnum].start; - uint32_t skip = label++; - if (m_impstate.fastram[ramnum].end != 0xffffffff) - { - UML_CMP(block, uml::I0, m_impstate.fastram[ramnum].end); // cmp i0, end - UML_JMPc(block, uml::COND_A, skip); // ja skip - } - if (m_impstate.fastram[ramnum].start != 0x00000000) - { - UML_CMP(block, uml::I0, m_impstate.fastram[ramnum].start); // cmp i0, fastram_start - UML_JMPc(block, uml::COND_B, skip); // jb skip - } - - if (!iswrite) - { - if (size == 1) - { - UML_XOR(block, uml::I0, uml::I0, (m_endian == ENDIANNESS_BIG) ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0)); - // xor i0, i0, bytexor - UML_LOAD(block, uml::I0, fastbase, uml::I0, uml::SIZE_BYTE, uml::SCALE_x1); // load i0, fastbase, i0, byte - } - else if (size == 2) - { - UML_XOR(block, uml::I0, uml::I0, (m_endian == ENDIANNESS_BIG) ? WORD_XOR_BE(0) : WORD_XOR_LE(0)); - // xor i0, i0, wordxor - UML_LOAD(block, uml::I0, fastbase, uml::I0, uml::SIZE_WORD, uml::SCALE_x1); // load i0, fastbase, i0, word_x1 - } - else if (size == 4) - { - UML_LOAD(block, uml::I0, fastbase, uml::I0, uml::SIZE_DWORD, uml::SCALE_x1); // load i0, fastbase, i0, dword_x1 - } - UML_RET(block); // ret - } - else - { - if (size == 1) - { - UML_XOR(block, uml::I0, uml::I0, (m_endian == ENDIANNESS_BIG) ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0)); - // xor i0, i0, bytexor - UML_STORE(block, fastbase, uml::I0, uml::I1, uml::SIZE_BYTE, uml::SCALE_x1); // store fastbase, i0, i1, byte - } - else if (size == 2) - { - UML_XOR(block, uml::I0, uml::I0, (m_endian == ENDIANNESS_BIG) ? WORD_XOR_BE(0) : WORD_XOR_LE(0)); - // xor i0, i0, wordxor - UML_STORE(block, fastbase, uml::I0, uml::I1, uml::SIZE_WORD, uml::SCALE_x1); // store fastbase, i0, i1, word_x1 - } - else if (size == 4) - { - UML_STORE(block, fastbase, uml::I0, uml::I1, uml::SIZE_DWORD, uml::SCALE_x1); // store fastbase,i0,i1,dword_x1 - } - UML_RET(block); // ret - } - - UML_LABEL(block, skip); // skip: - } - } - } - - switch (size) - { - case 1: - if (iswrite) - { - UML_WRITE(block, uml::I0, uml::I1, uml::SIZE_BYTE, uml::SPACE_PROGRAM); // write i0, i1, program_byte - } - else - { - UML_READ(block, uml::I0, uml::I0, uml::SIZE_BYTE, uml::SPACE_PROGRAM); // read i0, i0, program_byte - } - break; - - case 2: - if (iswrite) - { - UML_WRITE(block, uml::I0, uml::I1, uml::SIZE_WORD, uml::SPACE_PROGRAM); // write i0,i1,program_word - } - else - { - UML_READ(block, uml::I0, uml::I0, uml::SIZE_WORD, uml::SPACE_PROGRAM); // read i0,i0,program_word - } - break; - - case 4: - if (iswrite) - { - UML_WRITE(block, uml::I0, uml::I1, uml::SIZE_DWORD, uml::SPACE_PROGRAM); // write i0,i1,program_dword - } - else - { - UML_READ(block, uml::I0, uml::I0, uml::SIZE_DWORD, uml::SPACE_PROGRAM); // read i0,i0,program_dword - } - break; - } - UML_RET(block); // ret - - block.end(); -} - -/*************************************************************************** - CODE GENERATION -***************************************************************************/ - -/*------------------------------------------------- - generate_update_cycles - generate code to - subtract cycles from the icount and generate - an exception if out --------------------------------------------------*/ - -void arm7_cpu_device::generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param) -{ - /* check full interrupts if pending */ - if (compiler.checkints) - { - compiler.checkints = false; - UML_CALLH(block, *m_impstate.check_irq); - } - - /* account for cycles */ - if (compiler.cycles > 0) - { - UML_SUB(block, uml::mem(&m_icount), uml::mem(&m_icount), MAPVAR_CYCLES); // sub icount,icount,cycles - UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 - UML_EXHc(block, uml::COND_S, *m_impstate.out_of_cycles, param); // exh out_of_cycles,nextpc - } - compiler.cycles = 0; -} - - -/*------------------------------------------------- - generate_checksum_block - generate code to - validate a sequence of opcodes --------------------------------------------------*/ - -void arm7_cpu_device::generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast) -{ - const opcode_desc *curdesc; - if (m_impstate.drcuml->logging()) - { - block.append_comment("[Validation for %08X]", seqhead->pc); // comment - } - - /* loose verify or single instruction: just compare and fail */ - if (!(m_impstate.drcoptions & ARM7DRC_STRICT_VERIFY) || seqhead->next() == nullptr) - { - if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) - { - uint32_t sum = seqhead->opptr.l[0]; - const void *base = m_prptr(seqhead->physpc); - UML_LOAD(block, uml::I0, base, 0, uml::SIZE_DWORD, uml::SCALE_x4); // load i0,base,0,dword - - if (seqhead->delay.first() != nullptr && seqhead->physpc != seqhead->delay.first()->physpc) - { - base = m_prptr(seqhead->delay.first()->physpc); - UML_LOAD(block, uml::I1, base, 0, uml::SIZE_DWORD, uml::SCALE_x4); // load i1,base,dword - UML_ADD(block, uml::I0, uml::I0, uml::I1); // add i0,i0,i1 - - sum += seqhead->delay.first()->opptr.l[0]; - } - - UML_CMP(block, uml::I0, sum); // cmp i0,opptr[0] - UML_EXHc(block, uml::COND_NE, *m_impstate.nocode, epc(seqhead)); // exne nocode,seqhead->pc - } - } - - /* full verification; sum up everything */ - else - { - uint32_t sum = 0; - const void *base = m_prptr(seqhead->physpc); - UML_LOAD(block, uml::I0, base, 0, uml::SIZE_DWORD, uml::SCALE_x4); // load i0,base,0,dword - sum += seqhead->opptr.l[0]; - for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) - if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) - { - base = m_prptr(curdesc->physpc); - UML_LOAD(block, uml::I1, base, 0, uml::SIZE_DWORD, uml::SCALE_x4); // load i1,base,dword - UML_ADD(block, uml::I0, uml::I0, uml::I1); // add i0,i0,i1 - sum += curdesc->opptr.l[0]; - - if (curdesc->delay.first() != nullptr && (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc))) - { - base = m_prptr(curdesc->delay.first()->physpc); - UML_LOAD(block, uml::I1, base, 0, uml::SIZE_DWORD, uml::SCALE_x4); // load i1,base,dword - UML_ADD(block, uml::I0, uml::I0, uml::I1); // add i0,i0,i1 - sum += curdesc->delay.first()->opptr.l[0]; - } - } - UML_CMP(block, uml::I0, sum); // cmp i0,sum - UML_EXHc(block, uml::COND_NE, *m_impstate.nocode, epc(seqhead)); // exne nocode,seqhead->pc - } -} - - -/*------------------------------------------------- - generate_sequence_instruction - generate code - for a single instruction in a sequence --------------------------------------------------*/ - -void arm7_cpu_device::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - //offs_t expc; - int hotnum; - - /* add an entry for the log */ - // TODO FIXME -// if (m_impstate.drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP)) -// log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]); - - /* set the PC map variable */ - //expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc; - UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,pc - - /* accumulate total cycles */ - compiler.cycles += desc->cycles; - - /* update the icount map variable */ - UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles - - /* is this a hotspot? */ - for (hotnum = 0; hotnum < ARM7_MAX_HOTSPOTS; hotnum++) - { - if (m_impstate.hotspot[hotnum].pc != 0 && desc->pc == m_impstate.hotspot[hotnum].pc && desc->opptr.l[0] == m_impstate.hotspot[hotnum].opcode) - { - compiler.cycles += m_impstate.hotspot[hotnum].cycles; - break; - } - } - - /* update the icount map variable */ - UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles - - /* if we are debugging, call the debugger */ - if (debugger_enabled()) - { - UML_MOV(block, uml::mem(&R15), desc->pc); // mov [pc],desc->pc - save_fast_iregs(block); - UML_DEBUG(block, desc->pc); // debug desc->pc - } - - /* if we hit an unmapped address, fatal error */ - if (desc->flags & OPFLAG_COMPILER_UNMAPPED) - { - UML_MOV(block, uml::mem(&R15), desc->pc); // mov R15,desc->pc - save_fast_iregs(block); - UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE - } - - /* otherwise, unless this is a virtual no-op, it's a regular instruction */ - else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) - { - /* compile the instruction */ - if (!generate_opcode(block, compiler, desc)) - { - UML_MOV(block, uml::mem(&R15), desc->pc); // mov R15,desc->pc - UML_MOV(block, uml::mem(&m_impstate.arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l - //UML_CALLC(block, cfunc_unimplemented, arm); // callc cfunc_unimplemented // TODO FIXME - } - } -} - - -/*------------------------------------------------------------------ - generate_delay_slot_and_branch -------------------------------------------------------------------*/ - -void arm7_cpu_device::generate_delay_slot_and_branch(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t linkreg) -{ - compiler_state compiler_temp(compiler); - - /* update the cycles and jump through the hash table to the target */ - if (desc->targetpc != BRANCH_TARGET_DYNAMIC) - { - generate_update_cycles(block, compiler_temp, desc->targetpc); // <subtract cycles> - UML_HASHJMP(block, 0, desc->targetpc, *m_impstate.nocode); - // hashjmp 0,desc->targetpc,nocode - } - else - { - generate_update_cycles(block, compiler_temp, uml::mem(&m_impstate.jmpdest)); - // <subtract cycles> - UML_HASHJMP(block, 0, uml::mem(&m_impstate.jmpdest), *m_impstate.nocode);// hashjmp 0,<rsreg>,nocode - } - - /* update the label */ - compiler.labelnum = compiler_temp.labelnum; - - /* reset the mapvar to the current cycles and account for skipped slots */ - compiler.cycles += desc->skipslots; - UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles -} - - -const arm7_cpu_device::drcarm7ops_ophandler arm7_cpu_device::drcops_handler[0x10] = -{ - &arm7_cpu_device::drcarm7ops_0123, &arm7_cpu_device::drcarm7ops_0123, &arm7_cpu_device::drcarm7ops_0123, &arm7_cpu_device::drcarm7ops_0123, - &arm7_cpu_device::drcarm7ops_4567, &arm7_cpu_device::drcarm7ops_4567, &arm7_cpu_device::drcarm7ops_4567, &arm7_cpu_device::drcarm7ops_4567, - &arm7_cpu_device::drcarm7ops_89, &arm7_cpu_device::drcarm7ops_89, &arm7_cpu_device::drcarm7ops_ab, &arm7_cpu_device::drcarm7ops_ab, - &arm7_cpu_device::drcarm7ops_cd, &arm7_cpu_device::drcarm7ops_cd, &arm7_cpu_device::drcarm7ops_e, &arm7_cpu_device::drcarm7ops_f, -}; - -void arm7_cpu_device::saturate_qbit_overflow(drcuml_block &block) -{ - UML_MOV(block, uml::I1, 0); - UML_DCMP(block, uml::I0, 0x000000007fffffffL); - UML_MOVc(block, uml::COND_G, uml::I1, Q_MASK); - UML_MOVc(block, uml::COND_G, uml::I0, 0x7fffffff); - UML_DCMP(block, uml::I0, 0xffffffff80000000ULL); - UML_MOVc(block, uml::COND_L, uml::I1, Q_MASK); - UML_MOVc(block, uml::COND_L, uml::I0, 0x80000000); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); -} - -bool arm7_cpu_device::drcarm7ops_0123(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t insn) -{ - uml::code_label done; - /* Branch and Exchange (BX) */ - if ((insn & 0x0ffffff0) == 0x012fff10) // bits 27-4 == 000100101111111111110001 - { - UML_MOV(block, DRC_PC, DRC_REG(insn & 0x0f)); - UML_TEST(block, DRC_PC, 1); - UML_JMPc(block, uml::COND_Z, done = compiler.labelnum++); - UML_OR(block, DRC_CPSR, DRC_CPSR, T_MASK); - UML_AND(block, DRC_PC, DRC_PC, ~1); - } - else if ((insn & 0x0ff000f0) == 0x01600010) // CLZ - v5 - { - uint32_t rm = insn&0xf; - uint32_t rd = (insn>>12)&0xf; - - UML_LZCNT(block, DRC_REG(rd), DRC_REG(rm)); - UML_ADD(block, DRC_PC, DRC_PC, 4); - } - else if ((insn & 0x0ff000f0) == 0x01000050) // QADD - v5 - { - uint32_t rm = insn&0xf; - uint32_t rn = (insn>>16)&0xf; - uint32_t rd = (insn>>12)&0xf; - UML_DSEXT(block, uml::I0, DRC_REG(rm), uml::SIZE_DWORD); - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - UML_DADD(block, uml::I0, uml::I0, uml::I1); - saturate_qbit_overflow(block); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 4); - } - else if ((insn & 0x0ff000f0) == 0x01400050) // QDADD - v5 - { - uint32_t rm = insn&0xf; - uint32_t rn = (insn>>16)&0xf; - uint32_t rd = (insn>>12)&0xf; - - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - UML_DADD(block, uml::I0, uml::I1, uml::I1); - saturate_qbit_overflow(block); - - UML_DSEXT(block, uml::I0, DRC_REG(rm), uml::SIZE_DWORD); - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - UML_DADD(block, uml::I1, uml::I1, uml::I1); - UML_DADD(block, uml::I0, uml::I0, uml::I1); - saturate_qbit_overflow(block); - UML_MOV(block, DRC_REG(rd), uml::I0); - - UML_ADD(block, DRC_PC, DRC_PC, 4); - } - else if ((insn & 0x0ff000f0) == 0x01200050) // QSUB - v5 - { - uint32_t rm = insn&0xf; - uint32_t rn = (insn>>16)&0xf; - uint32_t rd = (insn>>12)&0xf; - - UML_DSEXT(block, uml::I0, DRC_REG(rm), uml::SIZE_DWORD); - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - UML_DSUB(block, uml::I0, uml::I0, uml::I1); - saturate_qbit_overflow(block); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 4); - } - else if ((insn & 0x0ff000f0) == 0x01600050) // QDSUB - v5 - { - uint32_t rm = insn&0xf; - uint32_t rn = (insn>>16)&0xf; - uint32_t rd = (insn>>12)&0xf; - - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - UML_DADD(block, uml::I0, uml::I1, uml::I1); - saturate_qbit_overflow(block); - - UML_DSEXT(block, uml::I0, DRC_REG(rm), uml::SIZE_DWORD); - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - UML_DADD(block, uml::I1, uml::I1, uml::I1); - UML_DSUB(block, uml::I0, uml::I0, uml::I1); - saturate_qbit_overflow(block); - UML_MOV(block, DRC_REG(rd), uml::I0); - - UML_ADD(block, DRC_PC, DRC_PC, 4); - } - else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5 - { - uint32_t rm = insn&0xf; - uint32_t rn = (insn>>8)&0xf; - uint32_t rd = (insn>>16)&0xf; - uint32_t ra = (insn>>12)&0xf; - - UML_MOV(block, uml::I0, DRC_REG(rm)); - UML_MOV(block, uml::I1, DRC_REG(rn)); - - // select top and bottom halves of src1/src2 and sign extend if necessary - if (insn & 0x20) - { - UML_SHR(block, uml::I0, uml::I0, 16); - } - UML_SEXT(block, uml::I0, uml::I0, uml::SIZE_WORD); - - if (insn & 0x40) - { - UML_SHR(block, uml::I1, uml::I1, 16); - } - UML_SEXT(block, uml::I0, uml::I0, uml::SIZE_WORD); - - // do the signed multiply - UML_MULS(block, uml::I0, uml::I1, uml::I0, uml::I1); - UML_DSHL(block, uml::I0, uml::I0, 32); - UML_DOR(block, uml::I0, uml::I0, uml::I1); - UML_MOV(block, uml::I1, DRC_REG(ra)); - UML_DADD(block, uml::I0, uml::I0, uml::I1); - // and the accumulate. NOTE: only the accumulate can cause an overflow, which is why we do it this way. - saturate_qbit_overflow(block); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 4); - } - else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5 - { - uint32_t rm = insn&0xf; - uint32_t rn = (insn>>8)&0xf; - uint32_t rdh = (insn>>16)&0xf; - uint32_t rdl = (insn>>12)&0xf; - - UML_DSEXT(block, uml::I0, DRC_REG(rm), uml::SIZE_DWORD); - UML_DSEXT(block, uml::I1, DRC_REG(rn), uml::SIZE_DWORD); - // do the signed multiply - UML_DMULS(block, uml::I2, uml::I3, uml::I0, uml::I1); - - UML_MOV(block, uml::I0, DRC_REG(rdh)); - UML_MOV(block, uml::I1, DRC_REG(rdl)); - UML_DSHL(block, uml::I0, uml::I0, 32); - UML_DOR(block, uml::I0, uml::I0, uml::I1); - UML_DADD(block, uml::I0, uml::I0, uml::I2); - UML_MOV(block, DRC_REG(rdl), uml::I0); - UML_DSHR(block, uml::I0, uml::I0, 32); - UML_MOV(block, DRC_REG(rdh), uml::I0); - } - else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5 - { - int32_t src1 = GetRegister(insn&0xf); - int32_t src2 = GetRegister((insn>>8)&0xf); - int32_t res; - - // select top and bottom halves of src1/src2 and sign extend if necessary - if (insn & 0x20) - { - src1 >>= 16; - } - - src1 &= 0xffff; - if (src1 & 0x8000) - { - src1 |= 0xffff0000; - } - - if (insn & 0x40) - { - src2 >>= 16; - } - - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff0000; - } - - res = src1 * src2; - SetRegister((insn>>16)&0xf, res); - R15 += 4; - } - else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5 - { - int32_t src1 = GetRegister(insn&0xf); - int32_t src2 = GetRegister((insn>>8)&0xf); - int64_t res; - - if (insn & 0x40) - { - src2 >>= 16; - } - else - { - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff; - } - } - - res = (int64_t)src1 * (int64_t)src2; - res >>= 16; - SetRegister((insn>>16)&0xf, (uint32_t)res); - } - else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5 - { - int32_t src1 = GetRegister(insn&0xf); - int32_t src2 = GetRegister((insn>>8)&0xf); - int32_t src3 = GetRegister((insn>>12)&0xf); - int64_t res; - - if (insn & 0x40) - { - src2 >>= 16; - } - else - { - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff; - } - } - - res = (int64_t)src1 * (int64_t)src2; - res >>= 16; - - // check for overflow and set the Q bit - saturate_qbit_overflow((int64_t)src3 + res); - - // do the real accumulate - src3 += (int32_t)res; - - // write the result back - SetRegister((insn>>16)&0xf, (uint32_t)res); - } - else - /* Multiply OR Swap OR Half Word Data Transfer */ - if ((insn & 0x0e000000) == 0 && (insn & 0x80) && (insn & 0x10)) // bits 27-25=000 bit 7=1 bit 4=1 - { - /* Half Word Data Transfer */ - if (insn & 0x60) // bits = 6-5 != 00 - { - HandleHalfWordDT(insn); - } - else - /* Swap */ - if (insn & 0x01000000) // bit 24 = 1 - { - HandleSwap(insn); - } - /* Multiply Or Multiply Long */ - else - { - /* multiply long */ - if (insn & 0x800000) // Bit 23 = 1 for Multiply Long - { - /* Signed? */ - if (insn & 0x00400000) - HandleSMulLong(insn); - else - HandleUMulLong(insn); - } - /* multiply */ - else - { - HandleMul(insn); - } - R15 += 4; - } - } - /* Data Processing OR PSR Transfer */ - else if ((insn & 0x0c000000) == 0) // bits 27-26 == 00 - This check can only exist properly after Multiplication check above - { - /* PSR Transfer (MRS & MSR) */ - if (((insn & 0x00100000) == 0) && ((insn & 0x01800000) == 0x01000000)) // S bit must be clear, and bit 24,23 = 10 - { - HandlePSRTransfer(insn); - ARM7_ICOUNT += 2; // PSR only takes 1 - S Cycle, so we add + 2, since at end, we -3.. - R15 += 4; - } - /* Data Processing */ - else - { - HandleALU(insn); - } - } - - UML_LABEL(block, done); - return true; -} - -bool arm7_cpu_device::drcarm7ops_4567(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op) -{ - return false; -} - -bool arm7_cpu_device::drcarm7ops_89(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op) -{ - return false; -} - -bool arm7_cpu_device::drcarm7ops_ab(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op) -{ - return false; -} - -bool arm7_cpu_device::drcarm7ops_cd(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op) -{ - return false; -} - -bool arm7_cpu_device::drcarm7ops_e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op) -{ - return false; -} - -bool arm7_cpu_device::drcarm7ops_f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t op) -{ - return false; -} - -/*------------------------------------------------- - generate_opcode - generate code for a specific - opcode --------------------------------------------------*/ - -bool arm7_cpu_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - //int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); - uint32_t op = desc->opptr.l[0]; - uint8_t opswitch = op >> 26; - uml::code_label skip; - uml::code_label contdecode; - uml::code_label unexecuted; - - if (T_IS_SET(GET_CPSR)) - { - // "In Thumb state, bit [0] is undefined and must be ignored. Bits [31:1] contain the PC." - UML_AND(block, uml::I0, DRC_PC, ~1); - } - else - { - UML_AND(block, uml::I0, DRC_PC, ~3); - } - - UML_TEST(block, uml::mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN - UML_MOVc(block, uml::COND_NZ, uml::I2, ARM7_TLB_ABORT_P | ARM7_TLB_READ); // movnz i0, ARM7_TLB_ABORT_P | ARM7_TLB_READ - UML_CALLHc(block, uml::COND_NZ, *m_impstate.tlb_translate); // callhnz tlb_translate); - - if (T_IS_SET(GET_CPSR)) - { - //UML_CALLH(block, *m_impstate.drcthumb[(op & 0xffc0) >> 6]); // callh drcthumb[op] // TODO FIXME - return true; - } - - switch (op >> INSN_COND_SHIFT) - { - case COND_EQ: - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_JMPc(block, uml::COND_Z, unexecuted = compiler.labelnum++); - break; - case COND_NE: - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_JMPc(block, uml::COND_NZ, unexecuted = compiler.labelnum++); - break; - case COND_CS: - UML_TEST(block, DRC_CPSR, C_MASK); - UML_JMPc(block, uml::COND_Z, unexecuted = compiler.labelnum++); - break; - case COND_CC: - UML_TEST(block, DRC_CPSR, C_MASK); - UML_JMPc(block, uml::COND_NZ, unexecuted = compiler.labelnum++); - break; - case COND_MI: - UML_TEST(block, DRC_CPSR, N_MASK); - UML_JMPc(block, uml::COND_Z, unexecuted = compiler.labelnum++); - break; - case COND_PL: - UML_TEST(block, DRC_CPSR, N_MASK); - UML_JMPc(block, uml::COND_NZ, unexecuted = compiler.labelnum++); - break; - case COND_VS: - UML_TEST(block, DRC_CPSR, V_MASK); - UML_JMPc(block, uml::COND_Z, unexecuted = compiler.labelnum++); - break; - case COND_VC: - UML_TEST(block, DRC_CPSR, V_MASK); - UML_JMPc(block, uml::COND_NZ, unexecuted = compiler.labelnum++); - break; - case COND_HI: - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_JMPc(block, uml::COND_NZ, unexecuted = compiler.labelnum++); - UML_TEST(block, DRC_CPSR, C_MASK); - UML_JMPc(block, uml::COND_Z, unexecuted = compiler.labelnum++); - break; - case COND_LS: - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_JMPc(block, uml::COND_NZ, contdecode = compiler.labelnum++); - UML_TEST(block, DRC_CPSR, C_MASK); - UML_JMPc(block, uml::COND_Z, contdecode); - UML_JMP(block, unexecuted); - break; - case COND_GE: - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_MOVc(block, uml::COND_NZ, uml::I0, 1); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_JMPc(block, uml::COND_NE, unexecuted); - break; - case COND_LT: - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_MOVc(block, uml::COND_NZ, uml::I0, 1); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_JMPc(block, uml::COND_E, unexecuted); - break; - case COND_GT: - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_JMPc(block, uml::COND_NZ, unexecuted); - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_MOVc(block, uml::COND_NZ, uml::I0, 1); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_JMPc(block, uml::COND_NE, unexecuted); - break; - case COND_LE: - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_MOVc(block, uml::COND_NZ, uml::I0, 1); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_JMPc(block, uml::COND_NE, contdecode); - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_JMPc(block, uml::COND_Z, unexecuted); - break; - case COND_NV: - UML_JMP(block, unexecuted); - break; - } - - UML_LABEL(block, contdecode); - - (this->*drcops_handler[(op & 0xF000000) >> 24])(block, compiler, desc, op); - - UML_LABEL(block, unexecuted); - UML_ADD(block, DRC_PC, DRC_PC, 4); - UML_ADD(block, MAPVAR_CYCLES, MAPVAR_CYCLES, 2); // add cycles, cycles, 2 - - UML_LABEL(block, skip); - - switch (opswitch) - { - /* ----- sub-groups ----- */ - - case 0x00: /* SPECIAL - MIPS I */ - return true; - - // TODO: FINISH ME - } - - return false; -} diff --git a/src/devices/cpu/arm7/arm7fe.hxx b/src/devices/cpu/arm7/arm7fe.hxx deleted file mode 100644 index 9cefd6f0f81..00000000000 --- a/src/devices/cpu/arm7/arm7fe.hxx +++ /dev/null @@ -1,458 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ryan Holtz -/*************************************************************************** - - arm7fe.hxx - - Front-end for ARM7 DRC - -***************************************************************************/ - -#include "emu.h" -#include "arm7.h" - - -//************************************************************************** -// ARM7 FRONTEND -//************************************************************************** - -// register flags 0 -#define REGFLAG_R(n) (((n) == 0) ? 0 : (1 << (n))) - -//------------------------------------------------- -// arm7_frontend - constructor -//------------------------------------------------- - -arm7_frontend::arm7_frontend(arm7_cpu_device *arm7, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) - : drc_frontend(*arm7, window_start, window_end, max_sequence), - m_arm7(arm7) -{ -} - - -//------------------------------------------------- -// describe_thumb - build a description of a -// thumb instruction -//------------------------------------------------- - -bool arm7_frontend::describe_thumb(opcode_desc &desc, const opcode_desc *prev) -{ - return false; -} - -//------------------------------------------------- -// describe_ops_* - build a description of -// an ARM7 instruction -//------------------------------------------------- - -bool arm7_frontend::describe_ops_0123(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - /* Branch and Exchange (BX) */ - if ((op & 0x0ffffff0) == 0x012fff10) // BX - { - } - else if ((op & 0x0ff000f0) == 0x01600010) // CLZ - v5 - { - } - else if ((op & 0x0ff000f0) == 0x01000050) // QADD - v5 - { - } - else if ((op & 0x0ff000f0) == 0x01400050) // QDADD - v5 - { - } - else if ((op & 0x0ff000f0) == 0x01200050) // QSUB - v5 - { - } - else if ((op & 0x0ff000f0) == 0x01600050) // QDSUB - v5 - { - } - else if ((op & 0x0ff00090) == 0x01000080) // SMLAxy - v5 - { - } - else if ((op & 0x0ff00090) == 0x01400080) // SMLALxy - v5 - { - } - else if ((op & 0x0ff00090) == 0x01600080) // SMULxy - v5 - { - } - else if ((op & 0x0ff000b0) == 0x012000a0) // SMULWy - v5 - { - } - else if ((op & 0x0ff000b0) == 0x01200080) // SMLAWy - v5 - { - } - else if ((op & 0x0e000000) == 0 && (op & 0x80) && (op & 0x10)) // Multiply OR Swap OR Half Word Data Transfer - { - if (op & 0x60) // Half Word Data Transfer - { - //HandleHalfWordDT(op); - } - else if (op & 0x01000000) // Swap - { - //HandleSwap(op); - } - else // Multiply Or Multiply Long - { - if (op & 0x800000) // Multiply long - { - if (op & 0x00400000) // Signed multiply - { - //HandleSMulLong(op); - } - else // Unsigned multiply - { - //HandleUMulLong(op); - } - } - else // Multiply - { - //HandleMul(op);// - } - } - } - else if ((op & 0x0c000000) == 0) // Data Processing OR PSR Transfer - { - if (((op & 0x00100000) == 0) && ((op & 0x01800000) == 0x01000000)) // PSR Transfer - - { - //HandlePSRTransfer(insn); - desc.cycles = 1; - } - else // Data processing - { - //HandleALU(insn); - } - } - return true; -} - -bool arm7_frontend::describe_ops_4567(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - if (op & INSN_I) - { - /* Register Shift */ - //off = decodeShift(op, nullptr); - } - else - { - /* Immediate Value */ - //off = op & INSN_SDT_IMM; - } - - uint32_t rn = (op & INSN_RN) >> INSN_RN_SHIFT; - - if (op & INSN_SDT_P) - { - /* Pre-indexed addressing */ - if ((get_mode32()) || (rn != eR15)) - { - //rnv = (GetRegister(rn) + off); - } - else - { - //rnv = (GET_PC + off); - } - - if (op & INSN_SDT_W) - { - //rnv_old = GetRegister(rn); - //SetRegister(rn, rnv); - } - else if (rn == eR15) - { - //rnv = rnv + 8; - } - } - else - { - /* Post-indexed addressing */ - if (rn == eR15) - { - if (get_mode32()) - { - //rnv = R15 + 8; - } - else - { - //rnv = GET_PC + 8; - } - } - else - { - //rnv = GetRegister(rn); - } - } - - /* Do the transfer */ - uint32_t rd = (op & INSN_RD) >> INSN_RD_SHIFT; - if (op & INSN_SDT_L) - { - /* Load */ - if (op & INSN_SDT_B) - { - //uint32_t data = READ8(rnv); - //SetRegister(rd, data); - } - else - { - //uint32_t data = READ32(rnv); - if (rd == eR15) - { - //R15 = data - 4; - // LDR, PC takes 2S + 2N + 1I (5 total cycles) - desc.cycles = 5; - } - else - { - //SetRegister(rd, data); - } - } - } - else - { - /* Store */ - if (op & INSN_SDT_B) - { - //WRITE8(rnv, (uint8_t) GetRegister(rd) & 0xffu); - } - else - { - //WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GetRegister(rd)); // manual says STR rd = PC, +12 - } - // Store takes only 2 N Cycles, so add + 1 - desc.cycles = 2; - } - - /* Do post-indexing writeback */ - if (!(op & INSN_SDT_P)/* && (insn & INSN_SDT_W)*/) - { - if (rd == rn) { - //SetRegister(rn, GetRegister(rd)); - } - else { - //SetRegister(rn, (rnv +/- off)); - } - } - return true; -} - -bool arm7_frontend::describe_ops_89(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - if ((op & 0x005f0f00) == 0x004d0500) - { - // unsupported (armv6 onwards only) - //arm9ops_undef(insn); - //R15 += 4; - } - else if ((op & 0x00500f00) == 0x00100a00) /* Return From Exception (RFE) */ - { - // unsupported (armv6 onwards only) - //arm9ops_undef(insn); - //R15 += 4; - } - else - { - //arm9ops_undef(insn); - //R15 += 4; - } - return false; -} - -bool arm7_frontend::describe_ops_ab(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - // BLX - //HandleBranch(insn, true); - //set_cpsr(GET_CPSR|T_MASK); - return true; -} - -bool arm7_frontend::describe_ops_cd(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - /* Additional coprocessor double register transfer */ - if ((op & 0x00e00000) == 0x00400000) - { - // unsupported - //arm9ops_undef(insn); - //R15 += 4; - } - else - { - //arm9ops_undef(insn); - //R15 += 4; - } - return false; -} - -bool arm7_frontend::describe_ops_e(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - /* Additional coprocessor register transfer */ - // unsupported - //arm9ops_undef(insn); - //R15 += 4; - return false; -} - -bool arm7_frontend::describe_ops_f(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - return false; -} - -//------------------------------------------------- -// describe_arm9_ops_* - build a description of -// an ARM9 instruction -//------------------------------------------------- - -bool describe_arm9_ops_1(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - /* Change processor state (CPS) */ - if ((op & 0x00f10020) == 0x00000000) - { - // unsupported (armv6 onwards only) - //arm9ops_undef(insn); - //R15 += 4; - } - else if ((op & 0x00ff00f0) == 0x00010000) /* set endianness (SETEND) */ - { - // unsupported (armv6 onwards only) - //arm9ops_undef(insn); - //R15 += 4; - } - else - { - //arm9ops_undef(insn); - //R15 += 4; - } - return false; -} - -bool describe_arm9_ops_57(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - /* Cache Preload (PLD) */ - if ((op & 0x0070f000) == 0x0050f000) - { - // unsupported (armv6 onwards only) - //arm9ops_undef(insn); - //R15 += 4; - } - else - { - //arm9ops_undef(insn); - //R15 += 4; - } - return false; -} - -bool describe_arm9_ops_89(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - return false; -} - -bool describe_arm9_ops_ab(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - return false; -} - -bool describe_arm9_ops_c(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - return false; -} - -bool describe_arm9_ops_e(opcode_desc &desc, const opcode_desc *prev, uint32_t op) -{ - return false; -} - - -uint32_t arm7_frontend::get_cpsr() -{ - return m_arm7->m_r[eCPSR]; -} - -bool arm7_frontend::get_mode32() -{ - return m_arm7->m_r[eCPSR] & SR_MODE32; -} - -//------------------------------------------------- -// describe - build a description of a single -// instruction -//------------------------------------------------- - -bool arm7_frontend::describe(opcode_desc &desc, const opcode_desc *prev) -{ - // compute the physical PC - const uint32_t cpsr = get_cpsr(); - assert((desc.physpc & (T_IS_SET(cpsr) ? 1 : 3)) == 0); - if (!m_arm7->arm7_tlb_translate(desc.physpc, ARM7_TLB_ABORT_P | ARM7_TLB_READ)) - { - // uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and - // mark as needing to validate; otherwise, just end the sequence here - desc.flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE; - return true; - } - - if (T_IS_SET(cpsr)) - { - return describe_thumb(desc, prev); - } - - // fetch the opcode - uint32_t op = desc.opptr.l[0] = m_arm7->m_direct->read_dword(desc.physpc); - - // all non-THUMB instructions are 4 bytes and default to 3 cycles each - desc.length = 4; - desc.cycles = 3; - - // parse the instruction - - int op_offset = 0; - if ((op >> INSN_COND_SHIFT) == COND_NV && m_arm7->m_archRev >= 5) - { - op_offset = 0x10; - } - - switch (((op & 0xF000000) >> 24) + op_offset) - { - case 0x0: case 0x1: case 0x2: case 0x3: - return describe_ops_0123(desc, prev, op); - - case 0x4: case 0x5: case 0x6: case 0x7: - return describe_ops_4567(desc, prev, op); - - case 0x8: case 0x9: - return describe_ops_89(desc, prev, op); - - case 0xa: case 0xb: - return describe_ops_ab(desc, prev, op); - - case 0xc: case 0xd: - return describe_ops_cd(desc, prev, op); - - case 0xe: - return describe_ops_e(desc, prev, op); - - case 0xf: - return describe_ops_f(desc, prev, op); - - case 0x11: // ARM9 - return describe_arm9_ops_1(desc, prev, op); - - case 0x15: case 0x17: // ARM9 - return describe_arm9_ops_57(desc, prev, op); - - case 0x18: case 0x19: // ARM9 - return describe_arm9_ops_89(desc, prev, op); - - case 0x1a: case 0x1b: // ARM9 - return describe_arm9_ops_ab(desc, prev, op); - - case 0x1c: // ARM9 - return describe_arm9_ops_c(desc, prev, op); - - case 0x1e: // ARM9 - return describe_arm9_ops_e(desc, prev, op); - - default: - return false; - } -} diff --git a/src/devices/cpu/arm7/arm7tdrc.hxx b/src/devices/cpu/arm7/arm7tdrc.hxx deleted file mode 100644 index 4fb16bb7562..00000000000 --- a/src/devices/cpu/arm7/arm7tdrc.hxx +++ /dev/null @@ -1,1592 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Steve Ellenoff,R. Belmont,Ryan Holtz -#include "emu.h" -#include "arm7core.h" -#include "arm7help.h" - - -const arm7_cpu_device::arm7thumb_drcophandler arm7_cpu_device::drcthumb_handler[0x40*0x10] = -{ -// #define THUMB_SHIFT_R ((uint16_t)0x0800) - &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, - &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, - &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, - &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, &arm7_cpu_device::drctg00_0, - &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, - &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, - &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, - &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, &arm7_cpu_device::drctg00_1, -// #define THUMB_INSN_ADDSUB ((uint16_t)0x0800) // #define THUMB_ADDSUB_TYPE ((uint16_t)0x0600) - &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, - &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, - &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, - &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, &arm7_cpu_device::drctg01_0, - &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, &arm7_cpu_device::drctg01_10, - &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, &arm7_cpu_device::drctg01_11, - &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, &arm7_cpu_device::drctg01_12, - &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, &arm7_cpu_device::drctg01_13, -// #define THUMB_INSN_CMP ((uint16_t)0x0800) - &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, - &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, - &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, - &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, &arm7_cpu_device::drctg02_0, - &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, - &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, - &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, - &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, &arm7_cpu_device::drctg02_1, -// #define THUMB_INSN_SUB ((uint16_t)0x0800) - &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, - &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, - &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, - &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, &arm7_cpu_device::drctg03_0, - &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, - &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, - &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, - &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, &arm7_cpu_device::drctg03_1, -//#define THUMB_GROUP4_TYPE ((uint16_t)0x0c00) //#define THUMB_ALUOP_TYPE ((uint16_t)0x03c0) // #define THUMB_HIREG_OP ((uint16_t)0x0300) // #define THUMB_HIREG_H ((uint16_t)0x00c0) - &arm7_cpu_device::drctg04_00_00, &arm7_cpu_device::drctg04_00_01, &arm7_cpu_device::drctg04_00_02, &arm7_cpu_device::drctg04_00_03, &arm7_cpu_device::drctg04_00_04, &arm7_cpu_device::drctg04_00_05, &arm7_cpu_device::drctg04_00_06, &arm7_cpu_device::drctg04_00_07, - &arm7_cpu_device::drctg04_00_08, &arm7_cpu_device::drctg04_00_09, &arm7_cpu_device::drctg04_00_0a, &arm7_cpu_device::drctg04_00_0b, &arm7_cpu_device::drctg04_00_0c, &arm7_cpu_device::drctg04_00_0d, &arm7_cpu_device::drctg04_00_0e, &arm7_cpu_device::drctg04_00_0f, - &arm7_cpu_device::drctg04_01_00, &arm7_cpu_device::drctg04_01_01, &arm7_cpu_device::drctg04_01_02, &arm7_cpu_device::drctg04_01_03, &arm7_cpu_device::drctg04_01_10, &arm7_cpu_device::drctg04_01_11, &arm7_cpu_device::drctg04_01_12, &arm7_cpu_device::drctg04_01_13, - &arm7_cpu_device::drctg04_01_20, &arm7_cpu_device::drctg04_01_21, &arm7_cpu_device::drctg04_01_22, &arm7_cpu_device::drctg04_01_23, &arm7_cpu_device::drctg04_01_30, &arm7_cpu_device::drctg04_01_31, &arm7_cpu_device::drctg04_01_32, &arm7_cpu_device::drctg04_01_33, - &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, - &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, - &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, - &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, &arm7_cpu_device::drctg04_0203, -//#define THUMB_GROUP5_TYPE ((uint16_t)0x0e00) - &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, &arm7_cpu_device::drctg05_0, - &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, &arm7_cpu_device::drctg05_1, - &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, &arm7_cpu_device::drctg05_2, - &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, &arm7_cpu_device::drctg05_3, - &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, &arm7_cpu_device::drctg05_4, - &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, &arm7_cpu_device::drctg05_5, - &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, &arm7_cpu_device::drctg05_6, - &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, &arm7_cpu_device::drctg05_7, -//#define THUMB_LSOP_L ((uint16_t)0x0800) - &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, - &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, - &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, - &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, &arm7_cpu_device::drctg06_0, - &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, - &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, - &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, - &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, &arm7_cpu_device::drctg06_1, -//#define THUMB_LSOP_L ((uint16_t)0x0800) - &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, - &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, - &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, - &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, &arm7_cpu_device::drctg07_0, - &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, - &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, - &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, - &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, &arm7_cpu_device::drctg07_1, -// #define THUMB_HALFOP_L ((uint16_t)0x0800) - &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, - &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, - &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, - &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, &arm7_cpu_device::drctg08_0, - &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, - &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, - &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, - &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, &arm7_cpu_device::drctg08_1, -// #define THUMB_STACKOP_L ((uint16_t)0x0800) - &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, - &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, - &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, - &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, &arm7_cpu_device::drctg09_0, - &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, - &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, - &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, - &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, &arm7_cpu_device::drctg09_1, -// #define THUMB_RELADDR_SP ((uint16_t)0x0800) - &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, - &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, - &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, - &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, &arm7_cpu_device::drctg0a_0, - &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, - &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, - &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, - &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, &arm7_cpu_device::drctg0a_1, -// #define THUMB_STACKOP_TYPE ((uint16_t)0x0f00) - &arm7_cpu_device::drctg0b_0, &arm7_cpu_device::drctg0b_0, &arm7_cpu_device::drctg0b_0, &arm7_cpu_device::drctg0b_0, &arm7_cpu_device::drctg0b_1, &arm7_cpu_device::drctg0b_1, &arm7_cpu_device::drctg0b_1, &arm7_cpu_device::drctg0b_1, - &arm7_cpu_device::drctg0b_2, &arm7_cpu_device::drctg0b_2, &arm7_cpu_device::drctg0b_2, &arm7_cpu_device::drctg0b_2, &arm7_cpu_device::drctg0b_3, &arm7_cpu_device::drctg0b_3, &arm7_cpu_device::drctg0b_3, &arm7_cpu_device::drctg0b_3, - &arm7_cpu_device::drctg0b_4, &arm7_cpu_device::drctg0b_4, &arm7_cpu_device::drctg0b_4, &arm7_cpu_device::drctg0b_4, &arm7_cpu_device::drctg0b_5, &arm7_cpu_device::drctg0b_5, &arm7_cpu_device::drctg0b_5, &arm7_cpu_device::drctg0b_5, - &arm7_cpu_device::drctg0b_6, &arm7_cpu_device::drctg0b_6, &arm7_cpu_device::drctg0b_6, &arm7_cpu_device::drctg0b_6, &arm7_cpu_device::drctg0b_7, &arm7_cpu_device::drctg0b_7, &arm7_cpu_device::drctg0b_7, &arm7_cpu_device::drctg0b_7, - &arm7_cpu_device::drctg0b_8, &arm7_cpu_device::drctg0b_8, &arm7_cpu_device::drctg0b_8, &arm7_cpu_device::drctg0b_8, &arm7_cpu_device::drctg0b_9, &arm7_cpu_device::drctg0b_9, &arm7_cpu_device::drctg0b_9, &arm7_cpu_device::drctg0b_9, - &arm7_cpu_device::drctg0b_a, &arm7_cpu_device::drctg0b_a, &arm7_cpu_device::drctg0b_a, &arm7_cpu_device::drctg0b_a, &arm7_cpu_device::drctg0b_b, &arm7_cpu_device::drctg0b_b, &arm7_cpu_device::drctg0b_b, &arm7_cpu_device::drctg0b_b, - &arm7_cpu_device::drctg0b_c, &arm7_cpu_device::drctg0b_c, &arm7_cpu_device::drctg0b_c, &arm7_cpu_device::drctg0b_c, &arm7_cpu_device::drctg0b_d, &arm7_cpu_device::drctg0b_d, &arm7_cpu_device::drctg0b_d, &arm7_cpu_device::drctg0b_d, - &arm7_cpu_device::drctg0b_e, &arm7_cpu_device::drctg0b_e, &arm7_cpu_device::drctg0b_e, &arm7_cpu_device::drctg0b_e, &arm7_cpu_device::drctg0b_f, &arm7_cpu_device::drctg0b_f, &arm7_cpu_device::drctg0b_f, &arm7_cpu_device::drctg0b_f, -// #define THUMB_MULTLS ((uint16_t)0x0800) - &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, - &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, - &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, - &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, &arm7_cpu_device::drctg0c_0, - &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, - &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, - &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, - &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, &arm7_cpu_device::drctg0c_1, -// #define THUMB_COND_TYPE ((uint16_t)0x0f00) - &arm7_cpu_device::drctg0d_0, &arm7_cpu_device::drctg0d_0, &arm7_cpu_device::drctg0d_0, &arm7_cpu_device::drctg0d_0, &arm7_cpu_device::drctg0d_1, &arm7_cpu_device::drctg0d_1, &arm7_cpu_device::drctg0d_1, &arm7_cpu_device::drctg0d_1, - &arm7_cpu_device::drctg0d_2, &arm7_cpu_device::drctg0d_2, &arm7_cpu_device::drctg0d_2, &arm7_cpu_device::drctg0d_2, &arm7_cpu_device::drctg0d_3, &arm7_cpu_device::drctg0d_3, &arm7_cpu_device::drctg0d_3, &arm7_cpu_device::drctg0d_3, - &arm7_cpu_device::drctg0d_4, &arm7_cpu_device::drctg0d_4, &arm7_cpu_device::drctg0d_4, &arm7_cpu_device::drctg0d_4, &arm7_cpu_device::drctg0d_5, &arm7_cpu_device::drctg0d_5, &arm7_cpu_device::drctg0d_5, &arm7_cpu_device::drctg0d_5, - &arm7_cpu_device::drctg0d_6, &arm7_cpu_device::drctg0d_6, &arm7_cpu_device::drctg0d_6, &arm7_cpu_device::drctg0d_6, &arm7_cpu_device::drctg0d_7, &arm7_cpu_device::drctg0d_7, &arm7_cpu_device::drctg0d_7, &arm7_cpu_device::drctg0d_7, - &arm7_cpu_device::drctg0d_8, &arm7_cpu_device::drctg0d_8, &arm7_cpu_device::drctg0d_8, &arm7_cpu_device::drctg0d_8, &arm7_cpu_device::drctg0d_9, &arm7_cpu_device::drctg0d_9, &arm7_cpu_device::drctg0d_9, &arm7_cpu_device::drctg0d_9, - &arm7_cpu_device::drctg0d_a, &arm7_cpu_device::drctg0d_a, &arm7_cpu_device::drctg0d_a, &arm7_cpu_device::drctg0d_a, &arm7_cpu_device::drctg0d_b, &arm7_cpu_device::drctg0d_b, &arm7_cpu_device::drctg0d_b, &arm7_cpu_device::drctg0d_b, - &arm7_cpu_device::drctg0d_c, &arm7_cpu_device::drctg0d_c, &arm7_cpu_device::drctg0d_c, &arm7_cpu_device::drctg0d_c, &arm7_cpu_device::drctg0d_d, &arm7_cpu_device::drctg0d_d, &arm7_cpu_device::drctg0d_d, &arm7_cpu_device::drctg0d_d, - &arm7_cpu_device::drctg0d_e, &arm7_cpu_device::drctg0d_e, &arm7_cpu_device::drctg0d_e, &arm7_cpu_device::drctg0d_e, &arm7_cpu_device::drctg0d_f, &arm7_cpu_device::drctg0d_f, &arm7_cpu_device::drctg0d_f, &arm7_cpu_device::drctg0d_f, -// #define THUMB_BLOP_LO ((uint16_t)0x0800) - &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, - &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, - &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, - &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, &arm7_cpu_device::drctg0e_0, - &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, - &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, - &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, - &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, &arm7_cpu_device::drctg0e_1, -// #define THUMB_BLOP_LO ((uint16_t)0x0800) - &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, - &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, - &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, - &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, &arm7_cpu_device::drctg0f_0, - &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, - &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, - &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, - &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, &arm7_cpu_device::drctg0f_1, -}; - - /* Shift operations */ - -void arm7_cpu_device::drctg00_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Shift left */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - int32_t offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT; - - UML_MOV(block, uml::I0, DRC_RS); // rrs - if (offs != 0) - { - UML_SHL(block, DRC_RD, DRC_RS, offs); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK); - UML_TEST(block, uml::I0, 1 << (31 - (offs - 1))); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - } - else - { - UML_MOV(block, DRC_RD, DRC_RS); - } - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_RD); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg00_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Shift right */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - int32_t offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT; - - UML_MOV(block, uml::I0, DRC_RS); // rrs - if (offs != 0) - { - UML_SHR(block, DRC_RD, DRC_RS, offs); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK); - UML_TEST(block, uml::I0, 1 << (31 - (offs - 1))); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - } - else - { - UML_MOV(block, DRC_RD, 0); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK); - UML_TEST(block, uml::I0, 0x80000000); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - } - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_RD); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Arithmetic */ - -void arm7_cpu_device::drctg01_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - int32_t offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT; - - /* ASR.. */ - UML_MOV(block, uml::I0, DRC_RS); - if (offs == 0) - { - offs = 32; - } - if (offs >= 32) - { - UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK); - UML_SHR(block, uml::I1, uml::I0, 31); - UML_TEST(block, uml::I1, ~0); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - UML_TEST(block, uml::I0, 0x80000000); - UML_MOVc(block, uml::COND_NZ, DRC_RD, ~0); - UML_MOVc(block, uml::COND_Z, DRC_RD, 0); - } - else - { - UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK); - UML_TEST(block, uml::I0, 1 << (offs - 1)); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - UML_SHR(block, uml::I1, uml::I0, offs); - UML_SHL(block, uml::I2, ~0, 32 - offs); - UML_TEST(block, uml::I0, 0x80000000); - UML_MOVc(block, uml::COND_Z, uml::I2, 0); - UML_OR(block, DRC_RD, uml::I1, uml::I2); - } - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_RD); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg01_10(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_ADD(block, DRC_REG(rd), DRC_REG(rs), DRC_REG(rn)); - DRCHandleThumbALUAddFlags(DRC_REG(rd), DRC_REG(rs), DRC_REG(rn)); -} - -void arm7_cpu_device::drctg01_11(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* SUB Rd, Rs, Rn */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_SUB(block, DRC_REG(rd), DRC_REG(rs), DRC_REG(rn)); - DRCHandleThumbALUSubFlags(DRC_REG(rd), DRC_REG(rs), DRC_REG(rn)); -} - -void arm7_cpu_device::drctg01_12(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD Rd, Rs, #imm */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_ADD(block, DRC_REG(rd), DRC_REG(rs), imm); - DRCHandleThumbALUAddFlags(DRC_REG(rd), DRC_REG(rs), imm); -} - -void arm7_cpu_device::drctg01_13(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* SUB Rd, Rs, #imm */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_SUB(block, DRC_REG(rd), DRC_REG(rs), imm); - DRCHandleThumbALUSubFlags(DRC_REG(rd), DRC_REG(rs), imm); -} - - /* CMP / MOV */ - -void arm7_cpu_device::drctg02_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - uint32_t op2 = (op & THUMB_INSN_IMM); - UML_MOV(block, DRC_REG(rd), op2); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg02_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - uint32_t op2 = op & THUMB_INSN_IMM; - - UML_SUB(block, uml::I3, DRC_REG(rn), op2); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rn), op2); -} - - /* ADD/SUB immediate */ - -void arm7_cpu_device::drctg03_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD Rd, #Offset8 */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - uint32_t op2 = op & THUMB_INSN_IMM; - uint32_t rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - UML_ADD(block, DRC_REG(rd), DRC_REG(rn), op2); - DRCHandleThumbALUAddFlags(DRC_REG(rd), DRC_REG(rn), op2); -} - -void arm7_cpu_device::drctg03_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* SUB Rd, #Offset8 */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - uint32_t op2 = op & THUMB_INSN_IMM; - uint32_t rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - UML_SUB(block, DRC_REG(rd), DRC_REG(rn), op2); - DRCHandleThumbALUSubFlags(DRC_REG(rd), DRC_REG(rn), op2); -} - - /* Rd & Rm instructions */ - -void arm7_cpu_device::drctg04_00_00(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* AND Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_AND(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs)); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_01(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* EOR Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_XOR(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs)); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_02(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LSL Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - uml::code_label skip; - uml::code_label offsg32; - uml::code_label offs32; - - UML_AND(block, uml::I1, DRC_REG(rs), 0xff); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK)); - - UML_CMP(block, uml::I1, 0); - UML_JMPc(block, uml::COND_E, skip = compiler.labelnum++); - - UML_CMP(block, uml::I1, 32); - UML_JMPc(block, uml::COND_A, offsg32 = compiler.labelnum++); - UML_JMPc(block, uml::COND_E, offs32 = compiler.labelnum++); - - UML_SHL(block, DRC_REG(rd), DRC_REG(rd), uml::I1); - UML_SUB(block, uml::I1, uml::I1, 1); - UML_SUB(block, uml::I1, 31, uml::I1); - UML_SHL(block, uml::I1, 1, uml::I1); - UML_TEST(block, DRC_REG(rd), uml::I1); - UML_MOVc(block, uml::COND_NZ, uml::I0, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_JMP(block, skip); - - UML_LABEL(block, offs32); - UML_TEST(block, DRC_REG(rd), 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_MOV(block, DRC_REG(rd), 0); - UML_JMP(block, skip); - - UML_LABEL(block, offsg32); - UML_MOV(block, DRC_REG(rd), 0); - - UML_LABEL(block, skip); - - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_03(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LSR Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - uml::code_label skip; - uml::code_label offsg32; - uml::code_label offs32; - - UML_AND(block, uml::I1, DRC_REG(rs), 0xff); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK)); - UML_CMP(block, uml::I1, 0); - UML_JMPc(block, uml::COND_E, skip = compiler.labelnum++); - - UML_CMP(block, uml::I1, 32); - UML_JMPc(block, uml::COND_A, offsg32 = compiler.labelnum++); - UML_JMPc(block, uml::COND_E, offs32 = compiler.labelnum++); - - UML_SHR(block, DRC_REG(rd), DRC_REG(rd), uml::I1); - UML_SUB(block, uml::I1, uml::I1, 1); // WP: TODO, Check this used to be "block, I1, 1" - UML_SHL(block, uml::I1, 1, uml::I1); - UML_TEST(block, DRC_REG(rd), uml::I1); - UML_MOVc(block, uml::COND_NZ, uml::I0, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_JMP(block, skip); - - UML_LABEL(block, offs32); - UML_TEST(block, DRC_REG(rd), 0x80000000); - UML_MOVc(block, uml::COND_NZ, uml::I0, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_MOV(block, DRC_REG(rd), 0); - UML_JMP(block, skip); - - UML_LABEL(block, offsg32); - UML_MOV(block, DRC_REG(rd), 0); - - UML_LABEL(block, skip); - - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_04(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ASR Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - uml::code_label skip; - uml::code_label offs32; - - UML_MOV(block, uml::I0, DRC_REG(rd)); - UML_AND(block, uml::I1, DRC_REG(rs), 0xff); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK)); - UML_CMP(block, uml::I1, 0); - UML_JMPc(block, uml::COND_E, skip = compiler.labelnum++); - - UML_SHR(block, uml::I2, uml::I0, uml::I1); - UML_SUB(block, uml::I1, 32, uml::I1); - UML_SHL(block, uml::I1, ~0, uml::I1); - UML_TEST(block, uml::I0, 0x80000000); - UML_MOVc(block, uml::COND_NZ, DRC_REG(rd), uml::I1); - UML_MOVc(block, uml::COND_Z, DRC_REG(rd), 0); - UML_OR(block, DRC_REG(rd), DRC_REG(rd), uml::I2); - UML_JMPc(block, uml::COND_B, offs32 = compiler.labelnum++); - - UML_TEST(block, uml::I0, 0x80000000); - UML_MOVc(block, uml::COND_NZ, DRC_REG(rd), ~0); - UML_MOVc(block, uml::COND_Z, DRC_REG(rd), 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - UML_JMP(block, skip); - - UML_LABEL(block, offs32); - UML_SUB(block, uml::I1, uml::I1, 1); - UML_SHL(block, uml::I1, 1, uml::I1); - UML_TEST(block, uml::I0, uml::I1); - UML_MOVc(block, uml::COND_NZ, uml::I1, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I1); - UML_JMP(block, skip); - - UML_LABEL(block, skip); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); - -} - -void arm7_cpu_device::drctg04_00_05(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADC Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_TEST(block, DRC_CPSR, C_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I3, 1); - UML_MOVc(block, uml::COND_Z, uml::I3, 0); - UML_ADD(block, uml::I3, uml::I3, DRC_REG(rd)); - UML_ADD(block, uml::I3, uml::I3, DRC_REG(rs)); - DRCHandleThumbALUAddFlags(uml::I3, DRC_REG(rd), DRC_REG(rs)); - UML_MOV(block, DRC_REG(rd), uml::I3); -} - -void arm7_cpu_device::drctg04_00_06(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* SBC Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_TEST(block, DRC_CPSR, C_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I3, 0); - UML_MOVc(block, uml::COND_Z, uml::I3, 1); - UML_SUB(block, uml::I3, DRC_REG(rs), uml::I3); - UML_ADD(block, uml::I3, DRC_REG(rd), uml::I3); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rd), DRC_REG(rs)); - UML_MOV(block, DRC_REG(rd), uml::I3); -} - -void arm7_cpu_device::drctg04_00_07(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ROR Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_MOV(block, uml::I0, DRC_REG(rd)); - UML_AND(block, uml::I1, DRC_REG(rs), 0x1f); - UML_SHR(block, DRC_REG(rd), uml::I0, uml::I1); - UML_SUB(block, uml::I2, 32, uml::I1); - UML_SHL(block, uml::I2, uml::I0, uml::I2); - UML_OR(block, DRC_REG(rd), DRC_REG(rd), uml::I2); - UML_SUB(block, uml::I1, uml::I1, 1); - UML_SHL(block, uml::I1, 1, uml::I1); - UML_TEST(block, uml::I0, uml::I1); - UML_MOVc(block, uml::COND_NZ, uml::I0, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_08(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* TST Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - UML_AND(block, uml::I2, DRC_REG(rd), DRC_REG(rs)); - DRCHandleALUNZFlags(uml::I2); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_09(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* NEG Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_MOV(block, uml::I3, DRC_REG(rs)); - UML_SUB(block, DRC_REG(rd), 0, uml::I3); - DRCHandleThumbALUSubFlags(DRC_REG(rd), 0, uml::I3); -} - -void arm7_cpu_device::drctg04_00_0a(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* CMP Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_SUB(block, uml::I3, DRC_REG(rd), DRC_REG(rs)); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rd), DRC_REG(rs)); -} - -void arm7_cpu_device::drctg04_00_0b(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* CMN Rd, Rs - check flags, add dasm */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_ADD(block, uml::I3, DRC_REG(rd), DRC_REG(rs)); - DRCHandleThumbALUAddFlags(uml::I3, DRC_REG(rd), DRC_REG(rs)); -} - -void arm7_cpu_device::drctg04_00_0c(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ORR Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_OR(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs)); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_0d(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* MUL Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - UML_MULU(block, DRC_REG(rd), uml::I1, DRC_REG(rd), DRC_REG(rs)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_0e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* BIC Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - UML_XOR(block, uml::I0, DRC_REG(rs), ~0); - UML_AND(block, DRC_REG(rd), DRC_REG(rd), uml::I0); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_00_0f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* MVN Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_XOR(block, uml::I0, DRC_REG(rs), ~0); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK)); - DRCHandleALUNZFlags(DRC_REG(rd)); - UML_OR(block, DRC_CPSR, DRC_CPSR, uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* ADD Rd, Rs group */ - -void arm7_cpu_device::drctg04_01_00(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: G4-1-0 Undefined Thumb instruction: %04x %x\n", pc, op, (op & THUMB_HIREG_H) >> THUMB_HIREG_H_SHIFT); -} - -void arm7_cpu_device::drctg04_01_01(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD Rd, HRs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_ADD(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs+8)); - if (rs == 7) - { - UML_ADD(block, DRC_REG(rd), DRC_REG(rd), 4); - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_01_02(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD HRd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), DRC_REG(rs)); - if (rd == 7) - { - UML_ADD(block, DRC_REG(rd), DRC_REG(rd), 4); - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_01_03(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Add HRd, HRs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), DRC_REG(rs+8)); - // emulate the effects of pre-fetch - if (rs == 7) - { - UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), 4); - } - if (rd == 7) - { - UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), 2); - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_01_10(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* CMP Rd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_SUB(block, uml::I3, DRC_REG(rd), DRC_REG(rs)); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rd), DRC_REG(rs)); -} - -void arm7_cpu_device::drctg04_01_11(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* CMP Rd, Hs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_SUB(block, uml::I3, DRC_REG(rd), DRC_REG(rs+8)); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rd), DRC_REG(rs+8)); -} - -void arm7_cpu_device::drctg04_01_12(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* CMP Hd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_SUB(block, uml::I3, DRC_REG(rd+8), DRC_REG(rs)); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rd+8), DRC_REG(rs)); -} - -void arm7_cpu_device::drctg04_01_13(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* CMP Hd, Hs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_SUB(block, uml::I3, DRC_REG(rd+8), DRC_REG(rs+8)); - DRCHandleThumbALUSubFlags(uml::I3, DRC_REG(rd+8), DRC_REG(rs+8)); -} - - /* MOV group */ - -void arm7_cpu_device::drctg04_01_20(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* MOV Rd, Rs (undefined) */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_MOV(block, DRC_REG(rd), DRC_REG(rs)); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_01_21(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* MOV Rd, Hs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_MOV(block, DRC_REG(rd), DRC_REG(rs+8)); - if (rs == 7) - { - UML_ADD(block, DRC_REG(rd), DRC_REG(rd), 4); - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg04_01_22(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* MOV Hd, Rs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_MOV(block, DRC_REG(rd+8), DRC_REG(rs)); - // CHECKME - if (rd != 7) - { - UML_ADD(block, DRC_PC, DRC_PC, 2); - } - else - { - UML_AND(block, DRC_PC, DRC_PC, ~1); - } -} - -void arm7_cpu_device::drctg04_01_23(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* MOV Hd, Hs */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - uint32_t rd = op & THUMB_HIREG_RD; - UML_MOV(block, DRC_REG(rd+8), DRC_REG(rs+8)); - if (rs == 7) - { - UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), 4); - } - if (rd != 7) - { - UML_ADD(block, DRC_PC, DRC_PC, 2); - } - else - { - UML_AND(block, DRC_PC, DRC_PC, ~1); - } - -} - -void arm7_cpu_device::drctg04_01_30(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uml::code_label switch_state; - uml::code_label done; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - UML_MOV(block, uml::I0, DRC_REG(rs)); - UML_TEST(block, uml::I0, 1); - UML_JMPc(block, uml::COND_Z, switch_state = compiler.labelnum++); - UML_AND(block, uml::I0, uml::I0, ~1); - UML_JMP(block, done = compiler.labelnum++); - - UML_LABEL(block, switch_state); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~T_MASK); - UML_TEST(block, uml::I0, 2); - UML_MOVc(block, uml::COND_NZ, uml::I1, 2); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_ADD(block, uml::I0, uml::I0, uml::I1); - - UML_LABEL(block, done); - UML_MOV(block, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg04_01_31(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uml::code_label switch_state; - uml::code_label done; - uint32_t rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT; - UML_MOV(block, uml::I0, DRC_REG(rs+8)); - if(rs == 7) - { - UML_ADD(block, uml::I0, uml::I0, 2); - } - UML_TEST(block, uml::I0, 1); - UML_JMPc(block, uml::COND_Z, switch_state = compiler.labelnum++); - UML_AND(block, uml::I0, uml::I0, ~1); - UML_JMP(block, done = compiler.labelnum++); - - UML_LABEL(block, switch_state); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~T_MASK); - UML_TEST(block, uml::I0, 2); - UML_MOVc(block, uml::COND_NZ, uml::I1, 2); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_ADD(block, uml::I0, uml::I0, uml::I1); - - UML_LABEL(block, done); - UML_MOV(block, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg04_01_32(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg04_01_33(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg04_0203(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT; - uint32_t imm = 4 + ((op & THUMB_INSN_IMM) << 2); - UML_AND(block, uml::I0, DRC_PC, ~2); - UML_ADD(block, uml::I0, uml::I0, imm); - UML_CALLH(block, *m_impstate.read32); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* LDR* STR* group */ - -void arm7_cpu_device::drctg05_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* STR Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.write32); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* STRH Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.write16); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* STRB Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.write16); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LDSB Rd, [Rn, Rm] todo, add dasm */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.read8); - UML_SEXT(block, DRC_REG(rd), uml::I0, uml::SIZE_BYTE); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LDR Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.read32); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_5(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LDRH Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.read16); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LDRB Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.read8); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg05_7(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* LDSH Rd, [Rn, Rm] */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; - uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; - uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), DRC_REG(rm)); - UML_CALLH(block, *m_impstate.read16); - UML_SEXT(block, DRC_REG(rd), uml::I0, uml::SIZE_WORD); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Word Store w/ Immediate Offset */ - -void arm7_cpu_device::drctg06_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Store */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = op & THUMB_ADDSUB_RD; - int32_t offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2; - UML_ADD(block, uml::I0, DRC_REG(rn), offs); - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_CALLH(block, *m_impstate.write32); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg06_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Load */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = op & THUMB_ADDSUB_RD; - int32_t offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2; - UML_ADD(block, uml::I0, DRC_REG(rn), offs); - UML_CALLH(block, *m_impstate.read32); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Byte Store w/ Immeidate Offset */ - -void arm7_cpu_device::drctg07_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Store */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = op & THUMB_ADDSUB_RD; - int32_t offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), offs); - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_CALLH(block, *m_impstate.write8); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg07_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Load */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = op & THUMB_ADDSUB_RD; - int32_t offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), offs); - UML_CALLH(block, *m_impstate.read8); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Load/Store Halfword */ - -void arm7_cpu_device::drctg08_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Store */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t offs = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT; - uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), offs << 1); - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_CALLH(block, *m_impstate.write16); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg08_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Load */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t offs = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT; - uint32_t rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; - uint32_t rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; - UML_ADD(block, uml::I0, DRC_REG(rn), offs << 1); - UML_CALLH(block, *m_impstate.read16); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Stack-Relative Load/Store */ - -void arm7_cpu_device::drctg09_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Store */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT; - int32_t offs = (uint8_t)(op & THUMB_INSN_IMM) << 2; - UML_ADD(block, uml::I0, DRC_REG(13), offs); - UML_MOV(block, uml::I1, DRC_REG(rd)); - UML_CALLH(block, *m_impstate.write32); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg09_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Load */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT; - uint32_t offs = (uint8_t)(op & THUMB_INSN_IMM) << 2; - UML_ADD(block, uml::I0, DRC_REG(13), offs); - UML_CALLH(block, *m_impstate.read32); - UML_MOV(block, DRC_REG(rd), uml::I0); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Get relative address */ - -void arm7_cpu_device::drctg0a_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD Rd, PC, #nn */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT; - int32_t offs = (uint8_t)(op & THUMB_INSN_IMM) << 2; - UML_ADD(block, uml::I0, DRC_PC, 4); - UML_AND(block, uml::I0, uml::I0, ~2); - UML_ADD(block, DRC_REG(rd), uml::I0, offs); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0a_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD Rd, SP, #nn */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT; - int32_t offs = (uint8_t)(op & THUMB_INSN_IMM) << 2; - UML_ADD(block, DRC_REG(rd), DRC_REG(13), offs); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Stack-Related Opcodes */ - -void arm7_cpu_device::drctg0b_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* ADD SP, #imm */ -{ - uint32_t op = desc->opptr.l[0]; - int32_t addr = (op & THUMB_INSN_IMM); - addr &= ~THUMB_INSN_IMM_S; - addr = ((op & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2)); - UML_ADD(block, DRC_REG(13), DRC_REG(13), addr); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0b_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* PUSH {Rlist} */ -{ - uint32_t op = desc->opptr.l[0]; - for (int32_t offs = 7; offs >= 0; offs--) - { - if (op & (1 << offs)) - { - UML_SUB(block, DRC_REG(13), DRC_REG(13), 4); - UML_MOV(block, uml::I0, DRC_REG(13)); - UML_MOV(block, uml::I1, DRC_REG(offs)); - UML_CALLH(block, *m_impstate.write32); - } - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0b_5(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* PUSH {Rlist}{LR} */ -{ - uint32_t op = desc->opptr.l[0]; - UML_SUB(block, DRC_REG(13), DRC_REG(13), 4); - UML_MOV(block, uml::I0, DRC_REG(13)); - UML_MOV(block, uml::I1, DRC_REG(14)); - UML_CALLH(block, *m_impstate.write32); - for (int32_t offs = 7; offs >= 0; offs--) - { - if (op & (1 << offs)) - { - UML_SUB(block, DRC_REG(13), DRC_REG(13), 4); - UML_MOV(block, uml::I0, DRC_REG(13)); - UML_MOV(block, uml::I1, DRC_REG(offs)); - UML_CALLH(block, *m_impstate.write32); - } - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0b_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_7(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_8(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_9(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_a(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_b(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_c(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* POP {Rlist} */ -{ - uint32_t op = desc->opptr.l[0]; - for (int32_t offs = 0; offs < 8; offs++) - { - if (op & (1 << offs)) - { - UML_MOV(block, uml::I0, DRC_REG(13)); - UML_CALLH(block, *m_impstate.read32); - UML_MOV(block, DRC_REG(offs), uml::I0); - UML_ADD(block, DRC_REG(13), DRC_REG(13), 4); - } - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0b_d(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* POP {Rlist}{PC} */ -{ - uint32_t op = desc->opptr.l[0]; - uml::code_label arch5up; - uml::code_label done; - uml::code_label switch_mode; - for (int32_t offs = 0; offs < 8; offs++) - { - if (op & (1 << offs)) - { - UML_MOV(block, uml::I0, DRC_REG(13)); - UML_CALLH(block, *m_impstate.read32); - UML_MOV(block, DRC_REG(offs), uml::I0); - UML_ADD(block, DRC_REG(13), DRC_REG(13), 4); - } - } - UML_MOV(block, uml::I0, DRC_REG(13)); - UML_CALLH(block, *m_impstate.read32); - UML_CMP(block, uml::mem(&m_archRev), 4); - UML_JMPc(block, uml::COND_A, arch5up = compiler.labelnum++); - UML_AND(block, DRC_PC, uml::I0, ~1); - - UML_LABEL(block, arch5up); - - UML_TEST(block, uml::I0, 1); - UML_JMPc(block, uml::COND_Z, switch_mode = compiler.labelnum++); - - UML_AND(block, uml::I0, uml::I0, ~1); - UML_MOV(block, DRC_PC, uml::I0); - UML_JMP(block, done); - - UML_LABEL(block, switch_mode); - UML_AND(block, DRC_CPSR, DRC_CPSR, ~T_MASK); - UML_TEST(block, uml::I0, 2); - UML_MOVc(block, uml::COND_NZ, uml::I1, 2); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_ADD(block, uml::I0, uml::I0, uml::I1); - UML_MOV(block, DRC_PC, uml::I0); - - UML_LABEL(block, done); - UML_ADD(block, DRC_REG(13), DRC_REG(13), 4); -} - -void arm7_cpu_device::drctg0b_e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -void arm7_cpu_device::drctg0b_f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op); -} - -/* Multiple Load/Store */ - -// "The address should normally be a word aligned quantity and non-word aligned addresses do not affect the instruction." -// "However, the bottom 2 bits of the address will appear on A[1:0] and might be interpreted by the memory system." - -// GBA "BB Ball" performs an unaligned read with A[1:0] = 2 and expects A[1] not to be ignored [BP 800B90A,(R4&3)!=0] -// GBA "Gadget Racers" performs an unaligned read with A[1:0] = 1 and expects A[0] to be ignored [BP B72,(R0&3)!=0] - -void arm7_cpu_device::drctg0c_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Store */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT; - UML_MOV(block, uml::I2, DRC_REG(rd)); - for (int32_t offs = 0; offs < 8; offs++) - { - if (op & (1 << offs)) - { - UML_AND(block, uml::I0, uml::I2, ~3); - UML_MOV(block, uml::I1, DRC_REG(offs)); - UML_CALLH(block, *m_impstate.write32); - UML_ADD(block, uml::I2, uml::I2, 4); - } - } - UML_MOV(block, DRC_REG(rd), uml::I2); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0c_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* Load */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT; - int rd_in_list = op & (1 << rd); - UML_MOV(block, uml::I2, DRC_REG(rd)); - for (int32_t offs = 0; offs < 8; offs++) - { - if (op & (1 << offs)) - { - UML_AND(block, uml::I0, uml::I2, ~1); - UML_CALLH(block, *m_impstate.read32); - UML_ADD(block, uml::I2, uml::I2, 4); - } - } - if (!rd_in_list) - { - UML_MOV(block, DRC_REG(rd), uml::I2); - } - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - - /* Conditional Branch */ - -void arm7_cpu_device::drctg0d_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_EQ: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_NE: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, offs); - UML_MOVc(block, uml::COND_NZ, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_CS: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, C_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_CC: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, offs); - UML_MOVc(block, uml::COND_NZ, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_MI: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_5(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_PL: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, offs); - UML_MOVc(block, uml::COND_NZ, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_VS: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_7(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_VC: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, offs); - UML_MOVc(block, uml::COND_NZ, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_8(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_HI: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, C_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I0, 1); - UML_MOVc(block, uml::COND_Z, uml::I0, 0); - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I1, 0); - UML_MOVc(block, uml::COND_Z, uml::I1, 1); - UML_AND(block, uml::I0, uml::I0, uml::I1); - UML_TEST(block, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_9(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_LS: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, C_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, 0); - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_AND(block, uml::I0, uml::I0, uml::I1); - UML_TEST(block, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_a(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_GE: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, 0); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_MOVc(block, uml::COND_E, uml::I0, offs); - UML_MOVc(block, uml::COND_NE, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_b(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_LT: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, 0); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_MOVc(block, uml::COND_NE, uml::I0, offs); - UML_MOVc(block, uml::COND_E, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_c(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_GT: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, 0); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_MOVc(block, uml::COND_E, uml::I0, 1); - UML_MOVc(block, uml::COND_NE, uml::I0, 0); - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_AND(block, uml::I0, uml::I0, uml::I1); - UML_TEST(block, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_d(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_LE: -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = ((int8_t)(op & THUMB_INSN_IMM) << 1) + 4; - UML_TEST(block, DRC_CPSR, N_MASK); - UML_MOVc(block, uml::COND_Z, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, 0); - UML_TEST(block, DRC_CPSR, V_MASK); - UML_MOVc(block, uml::COND_Z, uml::I1, 0); - UML_MOVc(block, uml::COND_NZ, uml::I1, 1); - UML_CMP(block, uml::I0, uml::I1); - UML_MOVc(block, uml::COND_NE, uml::I0, 1); - UML_MOVc(block, uml::COND_E, uml::I0, 0); - UML_TEST(block, DRC_CPSR, Z_MASK); - UML_MOVc(block, uml::COND_NZ, uml::I1, 0); - UML_MOVc(block, uml::COND_Z, uml::I1, 1); - UML_AND(block, uml::I0, uml::I0, uml::I1); - UML_TEST(block, uml::I0, 1); - UML_MOVc(block, uml::COND_NZ, uml::I0, offs); - UML_MOVc(block, uml::COND_Z, uml::I0, 2); - UML_ADD(block, DRC_PC, DRC_PC, uml::I0); -} - -void arm7_cpu_device::drctg0d_e(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // COND_AL: -{ - uint32_t op = desc->opptr.l[0]; - uint32_t pc = desc->pc; - fatalerror("%08x: Undefined Thumb instruction: %04x (ARM9 reserved)\n", pc, op); -} - -void arm7_cpu_device::drctg0d_f(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) // SWI (this is sort of a "hole" in the opcode encoding) -{ - UML_MOV(block, uml::mem(&m_pendingSwi), 1); - UML_CALLH(block, *m_impstate.check_irq); -} - - /* B #offs */ - -void arm7_cpu_device::drctg0e_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - int32_t offs = (op & THUMB_BRANCH_OFFS) << 1; - if (offs & 0x00000800) - { - offs |= 0xfffff800; - } - UML_ADD(block, DRC_PC, DRC_PC, offs + 4); -} - -void arm7_cpu_device::drctg0e_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t offs = (op & THUMB_BLOP_OFFS) << 1; - UML_MOV(block, uml::I0, DRC_REG(14)); - UML_ADD(block, uml::I0, uml::I0, offs); - UML_AND(block, uml::I0, uml::I0, ~3); - UML_ADD(block, DRC_REG(14), DRC_PC, 4); - UML_OR(block, DRC_REG(14), DRC_REG(14), 1); - UML_MOV(block, DRC_PC, uml::I0); -} - - /* BL */ - -void arm7_cpu_device::drctg0f_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - uint32_t addr = (op & THUMB_BLOP_OFFS) << 12; - if (addr & (1 << 22)) - { - addr |= 0xff800000; - } - addr += 4; - UML_ADD(block, DRC_REG(14), DRC_PC, addr); - UML_ADD(block, DRC_PC, DRC_PC, 2); -} - -void arm7_cpu_device::drctg0f_1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc) /* BL */ -{ - uint32_t op = desc->opptr.l[0]; - uint32_t addr = (op & THUMB_BLOP_OFFS) << 1; - UML_AND(block, uml::I0, DRC_REG(14), ~1); - UML_ADD(block, uml::I0, uml::I0, addr); - UML_ADD(block, DRC_REG(14), DRC_PC, 2); - UML_OR(block, DRC_REG(14), DRC_REG(14), 1); - UML_MOV(block, DRC_PC, uml::I0); -} diff --git a/src/devices/cpu/drcumlsh.h b/src/devices/cpu/drcumlsh.h index 6d6edf5921d..35aa71bf283 100644 --- a/src/devices/cpu/drcumlsh.h +++ b/src/devices/cpu/drcumlsh.h @@ -36,8 +36,6 @@ #define UML_HASHJMP(block, mode, pc, handle) do { using namespace uml; block.append().hashjmp(mode, pc, handle); } while (0) #define UML_JMP(block, label) do { using namespace uml; block.append().jmp(label); } while (0) #define UML_JMPc(block, cond, label) do { using namespace uml; block.append().jmp(cond, label); } while (0) -#define UML_JMPH(block, handle) do { using namespace uml; block.append().jmph(handle); } while (0) -#define UML_JMPHc(block, cond, handle) do { using namespace uml; block.append().jmph(cond, handle); } while (0) #define UML_EXH(block, handle, param) do { using namespace uml; block.append().exh(handle, param); } while (0) #define UML_EXHc(block, cond, handle, param) do { using namespace uml; block.append().exh(cond, handle, param); } while (0) #define UML_CALLH(block, handle) do { using namespace uml; block.append().callh(handle); } while (0) diff --git a/src/devices/cpu/uml.cpp b/src/devices/cpu/uml.cpp index 7663ee90208..5689e04cf4b 100644 --- a/src/devices/cpu/uml.cpp +++ b/src/devices/cpu/uml.cpp @@ -278,22 +278,6 @@ private: inst.m_param[pnum] = inst.param(pnum).immediate() & mask; } - static void normalise_commutative(instruction &inst) - { - const u64 mask = size_mask(inst); - - // truncate immediates to instruction size - truncate_immediate(inst, 1, mask); - truncate_immediate(inst, 2, mask); - - // if a source is the destination put it first, and put a single immediate last - if ((inst.param(0) == inst.param(2)) || (inst.param(1).is_immediate() && !inst.param(2).is_immediate())) - { - using std::swap; - swap(inst.m_param[1], inst.m_param[2]); - } - } - static void convert_to_mov_immediate(instruction &inst, u64 immediate) { u64 const mask = size_mask(inst); @@ -337,6 +321,22 @@ public: truncate_immediate(inst, i, mask); } + static void normalise_commutative(instruction &inst) + { + const u64 mask = size_mask(inst); + + // truncate immediates to instruction size + truncate_immediate(inst, 1, mask); + truncate_immediate(inst, 2, mask); + + // if a source is the destination put it first, and put a single immediate last + if ((inst.param(0) == inst.param(2)) || (inst.param(1).is_immediate() && !inst.param(2).is_immediate())) + { + using std::swap; + swap(inst.m_param[1], inst.m_param[2]); + } + } + static void read(instruction &inst) { // truncate immediate address to size @@ -799,6 +799,12 @@ public: inst.m_param[0] = val; inst.m_param[1] = val ? mask : 0; } + else if (inst.param(1).is_immediate_value(0)) + { + // testing against zero always produces the same result + inst.m_param[0] = 0; + inst.m_param[1] = 0; + } else if (inst.param(0) == inst.param(1)) { // testing a value against itself, turn the second operand into an immediate @@ -1224,7 +1230,7 @@ void uml::instruction::simplify() case OP_ROLAND: simplify_op::roland(*this); break; case OP_ROLINS: simplify_op::rolins(*this); break; case OP_ADD: simplify_op::add(*this); break; - case OP_ADDC: simplify_op::truncate_imm(*this); break; + case OP_ADDC: simplify_op::normalise_commutative(*this); break; case OP_SUB: simplify_op::sub(*this); break; case OP_SUBB: simplify_op::truncate_imm(*this); break; case OP_CMP: simplify_op::cmp(*this); break; diff --git a/src/devices/machine/vrender0.cpp b/src/devices/machine/vrender0.cpp index 831feed7409..c01fed77823 100644 --- a/src/devices/machine/vrender0.cpp +++ b/src/devices/machine/vrender0.cpp @@ -124,7 +124,7 @@ void vrender0soc_device::frame_map(address_map &map) void vrender0soc_device::device_add_mconfig(machine_config &config) { for (required_device<vr0uart_device> &uart : m_uart) - VRENDER0_UART(config, uart, 3579500); // DERIVED_CLOCK(1, 24)); + VRENDER0_UART(config, uart, 3'579'500); // DERIVED_CLOCK(1, 24)); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // evolution soccer defaults @@ -133,7 +133,7 @@ void vrender0soc_device::device_add_mconfig(machine_config &config) m_screen->screen_vblank().set(FUNC(vrender0soc_device::screen_vblank)); m_screen->set_palette(m_palette); - // runs at double speed wrt of the bus clock + // runs at double speed WRT the bus clock VIDEO_VRENDER0(config, m_vr0vid, DERIVED_CLOCK(1, 1)); PALETTE(config, m_palette, palette_device::RGB_565); @@ -340,7 +340,7 @@ void vrender0soc_device::TimerStart(int which) { int PD = (m_timer_control[which] >> 8) & 0xff; int TCV = m_timer_count[which] & 0xffff; - // TODO: documentation claims this is bus clock, half than internal PLL frequency. + // TODO: documentation claims this is bus clock, half the internal PLL frequency. attotime period = attotime::from_hz(this->clock()) * 2 * ((PD + 1) * (TCV + 1)); m_Timer[which]->adjust(period); diff --git a/src/mame/midway/midyunit.cpp b/src/mame/midway/midyunit.cpp index c10361c676d..03225090e9c 100644 --- a/src/mame/midway/midyunit.cpp +++ b/src/mame/midway/midyunit.cpp @@ -1074,25 +1074,25 @@ static INPUT_PORTS_START( yunittst ) PORT_INCLUDE(hiimpact) PORT_MODIFY("DSW") - PORT_DIPNAME( 0x80, 0x80, "RAM Test") PORT_DIPLOCATION("DS1:1") + PORT_DIPNAME( 0x80, 0x80, "RAM Test" ) PORT_DIPLOCATION("DS1:1") PORT_DIPSETTING( 0x80, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0x40, 0x40, "CMOS Test") PORT_DIPLOCATION("DS1:2") + PORT_DIPNAME( 0x40, 0x40, "CMOS Test" ) PORT_DIPLOCATION("DS1:2") PORT_DIPSETTING( 0x40, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0x20, 0x20, "Quick DMA Test") PORT_DIPLOCATION("DS1:3") + PORT_DIPNAME( 0x20, 0x20, "Quick DMA Test" ) PORT_DIPLOCATION("DS1:3") PORT_DIPSETTING( 0x20, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0x10, 0x10, "Harsh DMA Test") PORT_DIPLOCATION("DS1:4") + PORT_DIPNAME( 0x10, 0x10, "Harsh DMA Test" ) PORT_DIPLOCATION("DS1:4") PORT_DIPSETTING( 0x10, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0x08, 0x08, "ROM Checksums") PORT_DIPLOCATION("DS1:5") + PORT_DIPNAME( 0x08, 0x08, "ROM Checksums" ) PORT_DIPLOCATION("DS1:5") PORT_DIPSETTING( 0x08, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0x04, 0x04, "Switch Input Test") PORT_DIPLOCATION("DS1:6") + PORT_DIPNAME( 0x04, 0x04, "Switch Input Test" ) PORT_DIPLOCATION("DS1:6") PORT_DIPSETTING( 0x04, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0x02, 0x02, "Coin Counter Test") PORT_DIPLOCATION("DS1:7") + PORT_DIPNAME( 0x02, 0x02, "Coin Counter Test" ) PORT_DIPLOCATION("DS1:7") PORT_DIPSETTING( 0x02, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) PORT_DIPNAME( 0x01, 0x01, "Sound Port Test" ) PORT_DIPLOCATION("DS1:8") @@ -1100,29 +1100,28 @@ static INPUT_PORTS_START( yunittst ) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_DIPNAME( 0xc000, 0xc000, "Display Type") PORT_DIPLOCATION("DS2:1,2") + PORT_DIPNAME( 0xc000, 0xc000, "Display Type" ) PORT_DIPLOCATION("DS2:1,2") PORT_DIPSETTING( 0xc000, "Auto Sense") PORT_DIPSETTING( 0x4000, "4 Bit Y-Unit") PORT_DIPSETTING( 0x8000, "6 Bit Y-Unit") PORT_DIPSETTING( 0x0000, "8 Bit Y-Unit") - PORT_DIPNAME( 0x2000, 0x2000, "Screen Alignment") PORT_DIPLOCATION("DS2:3") + PORT_DIPNAME( 0x2000, 0x2000, "Screen Alignment" ) PORT_DIPLOCATION("DS2:3") PORT_DIPSETTING( 0x2000, DEF_STR( Off )) PORT_DIPSETTING( 0x0000, DEF_STR( On )) - PORT_DIPNAME( 0x1800, 0x1800, "Screen Fills") PORT_DIPLOCATION("DS2:4,5") + PORT_DIPNAME( 0x1800, 0x1800, "Screen Fills" ) PORT_DIPLOCATION("DS2:4,5") PORT_DIPSETTING( 0x1800, "Nothing") PORT_DIPSETTING( 0x0800, "Red") PORT_DIPSETTING( 0x1000, "Green") PORT_DIPSETTING( 0x0000, "Blue") - PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unused )) PORT_DIPLOCATION("DS2:6") + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unused )) PORT_DIPLOCATION("DS2:6") PORT_DIPSETTING( 0x0400, DEF_STR( Off )) PORT_DIPSETTING( 0x0000, DEF_STR( On )) - PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unused )) PORT_DIPLOCATION("DS2:7") + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unused )) PORT_DIPLOCATION("DS2:7") PORT_DIPSETTING( 0x0200, DEF_STR( Off )) PORT_DIPSETTING( 0x0000, DEF_STR( On )) - PORT_DIPNAME( 0x0100, 0x0100, "Williams Logo" ) PORT_DIPLOCATION("DS2:8") + PORT_DIPNAME( 0x0100, 0x0100, "Williams Logo" ) PORT_DIPLOCATION("DS2:8") PORT_DIPSETTING( 0x0100, DEF_STR( Off )) PORT_DIPSETTING( 0x0000, DEF_STR( On )) - INPUT_PORTS_END /************************************* diff --git a/src/mame/misc/crystal.cpp b/src/mame/misc/crystal.cpp index df26d905ce8..fca3b647ceb 100644 --- a/src/mame/misc/crystal.cpp +++ b/src/mame/misc/crystal.cpp @@ -164,7 +164,8 @@ public: m_ds1302(*this, "rtc"), m_eeprom(*this, "eeprom"), m_dsw(*this, "DSW"), - m_system(*this, "SYSTEM") + m_system(*this, "SYSTEM"), + m_lamps(*this, "lamp%u", 1U) { } void init_topbladv() ATTR_COLD; @@ -199,6 +200,8 @@ private: required_ioport m_dsw; required_ioport m_system; + output_finder<16> m_lamps; + std::unique_ptr<uint8_t[]> m_dummy_region; uint32_t m_bank; @@ -208,6 +211,7 @@ private: uint32_t system_input_r(); void banksw_w(uint32_t data); + void lamps_w(offs_t offset, u8 data); uint32_t flashcmd_r(); void flashcmd_w(uint32_t data); void coin_counters_w(uint8_t data); @@ -233,6 +237,12 @@ void crystal_state::banksw_w(uint32_t data) m_mainbank->set_entry(m_bank); } +void crystal_state::lamps_w(offs_t offset, uint8_t data) +{ + for (unsigned i = 0; 8 > i; ++i) + m_lamps[(offset << 3) | i] = BIT(data, i); +} + uint32_t crystal_state::pioldat_r() { return m_pio; @@ -303,6 +313,7 @@ void crystal_state::crystal_mem(address_map &map) map(0x01200008, 0x0120000b).r(FUNC(crystal_state::system_input_r)); map(0x01280000, 0x01280003).w(FUNC(crystal_state::banksw_w)); + map(0x01320000, 0x01320003).umask32(0x00ff00ff).w(FUNC(crystal_state::lamps_w)); map(0x01400000, 0x0140ffff).ram().share("nvram"); map(0x01800000, 0x01ffffff).m(m_vr0soc, FUNC(vrender0soc_device::regs_map)); @@ -374,6 +385,8 @@ loop: void crystal_state::machine_start() { + m_lamps.resolve(); + patchreset(); if (m_mainbank) @@ -551,14 +564,17 @@ INPUT_PORTS_END static INPUT_PORTS_START( urachamu ) PORT_INCLUDE( officeye ) - // oddly they reversed red and blue + // uses blue/yellow/red rather than red/green/blue PORT_MODIFY("P1_P2") - PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Blue") - PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Red") - PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Blue") - PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 Blue") - PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Red") - PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 Red") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Blue") + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Yellow") + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Red") + PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Blue") + PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 Blue") + PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Yellow") + PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 Yellow") + PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Red") + PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 Red") INPUT_PORTS_END static INPUT_PORTS_START( wulybuly ) diff --git a/src/mame/namco/namcos23.cpp b/src/mame/namco/namcos23.cpp index 2807297a314..fc1f5948413 100644 --- a/src/mame/namco/namcos23.cpp +++ b/src/mame/namco/namcos23.cpp @@ -6689,7 +6689,7 @@ static INPUT_PORTS_START(aking) PORT_BIT(0xffff, 0x8000, IPT_AD_STICK_Y) PORT_MINMAX(0x0100, 0xffff) PORT_SENSITIVITY(100) PORT_KEYDELTA(2560) PORT_NAME("Rod Pitch") PORT_MODIFY("JVS_ROTARY_INPUT1") - PORT_BIT(0xffff, 0, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(8) PORT_NAME("Reel") + PORT_BIT(0xffff, 0, IPT_DIAL_V) PORT_SENSITIVITY(100) PORT_KEYDELTA(8) PORT_NAME("Reel") INPUT_PORTS_END static INPUT_PORTS_START(downhill) @@ -6708,7 +6708,7 @@ static INPUT_PORTS_START(downhill) PORT_BIT(0xffff, 0x8000, IPT_PADDLE) PORT_SENSITIVITY(100) PORT_KEYDELTA(2560) PORT_NAME("Steering") PORT_MODIFY("JVS_ROTARY_INPUT1") - PORT_BIT(0xffff, 0, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(8) PORT_NAME("Encoder") + PORT_BIT(0xffff, 0, IPT_DIAL_V) PORT_SENSITIVITY(100) PORT_KEYDELTA(8) PORT_NAME("Encoder") INPUT_PORTS_END static INPUT_PORTS_START(finfurl) diff --git a/src/mame/pinball/criter75.cpp b/src/mame/pinball/criter75.cpp index a1586d68bc3..35166a1a0b0 100644 --- a/src/mame/pinball/criter75.cpp +++ b/src/mame/pinball/criter75.cpp @@ -78,21 +78,22 @@ namespace { class criter75_state : public driver_device { public: - criter75_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), + criter75_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu") { } void criter75(machine_config &config); -private: - // devices - required_device<netlist_mame_device> m_maincpu; - +protected: // driver_device overrides virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; + +private: + // devices + required_device<netlist_mame_device> m_maincpu; }; static NETLIST_START(criter75) |
