diff --git a/Makefile b/Makefile index 3057626f..8d240752 100644 --- a/Makefile +++ b/Makefile @@ -2528,7 +2528,7 @@ ifeq ($(HAVE_VM_COMPILED),true) $(B)/ded/vm_x86.o endif ifneq ($(findstring $(ARCH),ppc ppc64),) - Q3DOBJ += $(B)/ded/vm_powerpc.o $(B)/ded/vm_powerpc_asm.o + Q3DOBJ += $(B)/ded/vm_powerpc.o endif ifeq ($(ARCH),sparc) Q3DOBJ += $(B)/ded/vm_sparc.o diff --git a/cmake/shared_sources.cmake b/cmake/shared_sources.cmake index 5124d495..c2d7af0c 100644 --- a/cmake/shared_sources.cmake +++ b/cmake/shared_sources.cmake @@ -42,7 +42,6 @@ if(ARCH MATCHES "x86" OR ARCH MATCHES "x86_64") elseif(ARCH MATCHES "ppc" OR ARCH MATCHES "ppc64") list(APPEND COMMON_SOURCES ${SOURCE_DIR}/qcommon/vm_powerpc.c - ${SOURCE_DIR}/qcommon/vm_powerpc_asm.c ) elseif(ARCH MATCHES "arm") list(APPEND COMMON_SOURCES diff --git a/code/qcommon/vm_powerpc.c b/code/qcommon/vm_powerpc.c index 75e10aaa..20550f5b 100644 --- a/code/qcommon/vm_powerpc.c +++ b/code/qcommon/vm_powerpc.c @@ -25,13 +25,1101 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include +#include +#include #ifndef MAP_ANONYMOUS # define MAP_ANONYMOUS MAP_ANON #endif #include "vm_local.h" -#include "vm_powerpc_asm.h" + +/* + * Register information according to: + * http://refspecs.freestandards.org/elf/elfspec_ppc.pdf + */ + +#define r0 0 // volatile +#define r1 1 // caller safe ( stack pointer ) +#define r2 2 // reserved +#define r3 3 // callee safe +#define r4 4 // callee safe +#define r5 5 // callee safe +#define r6 6 // callee safe +#define r7 7 // callee safe +#define r8 8 // callee safe +#define r9 9 // callee safe +#define r10 10 // callee safe +#define r11 11 // volatile +#define r12 12 // volatile +#define r13 13 // reserved ( small data area ) +#define r14 14 // caller safe +#define r15 15 // caller safe +#define r16 16 // caller safe +#define r17 17 // caller safe +#define r18 18 // caller safe +#define r19 19 // caller safe +#define r20 20 // caller safe +#define r21 21 // caller safe +#define r22 22 // caller safe +#define r23 23 // caller safe +#define r24 24 // caller safe +#define r25 25 // caller safe +#define r26 26 // caller safe +#define r27 27 // caller safe +#define r28 28 // caller safe +#define r29 29 // caller safe +#define r30 30 // caller safe +#define r31 31 // caller safe ( environment pointers ) + +#define f0 0 // callee safe +#define f1 1 // callee safe +#define f2 2 // callee safe +#define f3 3 // callee safe +#define f4 4 // callee safe +#define f5 5 // callee safe +#define f6 6 // callee safe +#define f7 7 // callee safe +#define f8 8 // callee safe +#define f9 9 // callee safe +#define f10 10 // callee safe +#define f11 11 // callee safe +#define f12 12 // callee safe +#define f13 13 // callee safe +#define f14 14 // caller safe +#define f15 15 // caller safe +#define f16 16 // caller safe +#define f17 17 // caller safe +#define f18 18 // caller safe +#define f19 19 // caller safe +#define f20 20 // caller safe +#define f21 21 // caller safe +#define f22 22 // caller safe +#define f23 23 // caller safe +#define f24 24 // caller safe +#define f25 25 // caller safe +#define f26 26 // caller safe +#define f27 27 // caller safe +#define f28 28 // caller safe +#define f29 29 // caller safe +#define f30 30 // caller safe +#define f31 31 // caller safe + +#define cr0 0 // volatile +#define cr1 1 // volatile +#define cr2 2 // caller safe +#define cr3 3 // caller safe +#define cr4 4 // caller safe +#define cr5 5 // volatile +#define cr6 6 // volatile +#define cr7 7 // volatile + +#define lt 0 +#define gt 1 +#define eq 2 +#define so 3 + +// branch bo field values +#define branchLikely 1 +#define branchFalse 4 +#define branchTrue 12 +#define branchAlways 20 + +// branch extensions (change branch type) +#define branchExtLink 0x0001 + + +/* + * This list must match exactly the powerpc_opcodes list from vm_powerpc_asm.c + * If you're changing the original list remember to regenerate this one. You + * may do so using this perl script: + perl -p -e 'BEGIN{%t=("-"=>m=>"+"=>p=>"."=>d=>);$l=""}$o=0 if/^}/; + if($o && s/^{ "(.*?)([\.+-])?".+/i\U$1\E$t{$2}/s){$_.="_" while$l{$_}; + $l{$_}=1;if(length $l.$_ > 70){$s=$_;$_="\t$l\n";$l="$s,"}else + {$l.=" $_,";$_=undef}}else{$o=1 if/powerpc_opcodes.*=/;$_=undef}; + END{print "\t$l\n"}' < vm_powerpc_asm.c + */ + +typedef enum powerpc_iname { + iCMPLWI, iCMPWI, iCMPW, iCMPLW, iFCMPU, iLI, iLIS, iADDI, iADDIS, + iBLTm, iBC, iBCL, iB, iBL, iBLR, iBCTR, iBCTRL, iRLWINM, iNOP, iORI, + iXORIS, iLDX, iLWZX, iSLW, iAND, iSUB, iLBZX, iNEG, iNOT, iSTWX, iSTBX, + iMULLW, iADD, iLHZX, iXOR, iMFLR, iSTHX, iMR, iOR, iDIVWU, iMTLR, + iMTCTR, iDIVW, iLFSX, iSRW, iSTFSX, iSRAW, iEXTSH, iEXTSB, iLWZ, iLBZ, + iSTW, iSTWU, iSTB, iLHZ, iSTH, iLFS, iLFD, iSTFS, iSTFD, iLD, iFDIVS, + iFSUBS, iFADDS, iFMULS, iSTD, iSTDU, iFRSP, iFCTIWZ, iFSUB, iFNEG, +} powerpc_iname_t; + +#include + +typedef uint32_t ppc_instruction_t; + +extern ppc_instruction_t +asm_instruction( powerpc_iname_t, const int, const long int * ); + +#define IN( inst, args... ) \ +({\ + const long int argv[] = { args };\ + const int argc = sizeof( argv ) / sizeof( argv[0] ); \ + asm_instruction( inst, argc, argv );\ +}) + +/* return nop on error */ +#define ASM_ERROR_OPC (0x60000000) + +/* + * BEGIN OF ppc.h + */ + +#define ppc_cpu_t int + +struct powerpc_opcode +{ + const char *name; + unsigned long opcode; + unsigned long mask; + ppc_cpu_t flags; + unsigned char operands[8]; +}; + +static const struct powerpc_opcode powerpc_opcodes[]; + +#define PPC_OPCODE_PPC 1 +#define PPC_OPCODE_POWER 2 +#define PPC_OPCODE_POWER2 4 +#define PPC_OPCODE_32 8 +#define PPC_OPCODE_64 0x10 +#define PPC_OPCODE_601 0x20 +#define PPC_OPCODE_COMMON 0x40 +#define PPC_OPCODE_ANY 0x80 +#define PPC_OPCODE_64_BRIDGE 0x100 +#define PPC_OPCODE_ALTIVEC 0x200 +#define PPC_OPCODE_403 0x400 +#define PPC_OPCODE_BOOKE 0x800 +#define PPC_OPCODE_BOOKE64 0x1000 +#define PPC_OPCODE_440 0x2000 +#define PPC_OPCODE_POWER4 0x4000 +#define PPC_OPCODE_NOPOWER4 0x8000 +#define PPC_OPCODE_CLASSIC 0x10000 +#define PPC_OPCODE_SPE 0x20000 +#define PPC_OPCODE_ISEL 0x40000 +#define PPC_OPCODE_EFS 0x80000 +#define PPC_OPCODE_BRLOCK 0x100000 +#define PPC_OPCODE_PMR 0x200000 +#define PPC_OPCODE_CACHELCK 0x400000 +#define PPC_OPCODE_RFMCI 0x800000 +#define PPC_OPCODE_POWER5 0x1000000 +#define PPC_OPCODE_E300 0x2000000 +#define PPC_OPCODE_POWER6 0x4000000 +#define PPC_OPCODE_CELL 0x8000000 +#define PPC_OPCODE_PPCPS 0x10000000 +#define PPC_OPCODE_E500MC 0x20000000 +#define PPC_OPCODE_405 0x40000000 +#define PPC_OPCODE_VSX 0x80000000 + +#define PPC_OP(i) (((i) >> 26) & 0x3f) + +struct powerpc_operand +{ + unsigned int bitm; + int shift; + unsigned long (*insert) + (unsigned long, long, int, const char **); + unsigned long flags; +}; + +static const struct powerpc_operand powerpc_operands[]; + +#define PPC_OPERAND_SIGNED (0x1) +#define PPC_OPERAND_SIGNOPT (0x2) +#define PPC_OPERAND_FAKE (0x4) +#define PPC_OPERAND_PARENS (0x8) +#define PPC_OPERAND_CR (0x10) +#define PPC_OPERAND_GPR (0x20) +#define PPC_OPERAND_GPR_0 (0x40) +#define PPC_OPERAND_FPR (0x80) +#define PPC_OPERAND_RELATIVE (0x100) +#define PPC_OPERAND_ABSOLUTE (0x200) +#define PPC_OPERAND_OPTIONAL (0x400) +#define PPC_OPERAND_NEXT (0x800) +#define PPC_OPERAND_NEGATIVE (0x1000) +#define PPC_OPERAND_VR (0x2000) +#define PPC_OPERAND_DS (0x4000) +#define PPC_OPERAND_DQ (0x8000) +#define PPC_OPERAND_PLUS1 (0x10000) +#define PPC_OPERAND_FSL (0x20000) +#define PPC_OPERAND_FCR (0x40000) +#define PPC_OPERAND_UDI (0x80000) +#define PPC_OPERAND_VSR (0x100000) + +/* + * END OF ppc.h + */ + +#define PPC_DEST_ARCH PPC_OPCODE_PPC + +ppc_instruction_t +asm_instruction( powerpc_iname_t sname, const int argc, const long int *argv ) +{ + const char *errmsg = NULL; + const char *name; + unsigned long int ret; + const struct powerpc_opcode *opcode = NULL; + int argi, argj; + + opcode = &powerpc_opcodes[ sname ]; + name = opcode->name; + + if ( ! opcode ) { + printf( "Can't find opcode %d\n", sname ); + return ASM_ERROR_OPC; + } + if ( ( opcode->flags & PPC_DEST_ARCH ) != PPC_DEST_ARCH ) { + printf( "opcode %s not defined for this arch\n", name ); + return ASM_ERROR_OPC; + } + + ret = opcode->opcode; + + argi = argj = 0; + while ( opcode->operands[ argi ] != 0 ) { + long int op = 0; + const struct powerpc_operand *operand = &powerpc_operands[ opcode->operands[ argi ] ]; + + if ( ! (operand->flags & PPC_OPERAND_FAKE) ) { + if ( argj >= argc ) { + printf( "Not enough arguments for %s, got %d\n", name, argc ); + return ASM_ERROR_OPC; + } + + op = argv[ argj++ ]; + } + + if ( operand->insert ) { + errmsg = NULL; + ret = operand->insert( ret, op, PPC_DEST_ARCH, &errmsg ); + if ( errmsg ) { + printf( "%s: error while inserting operand %d (0x%.2lx): %s\n", + name, argi, op, errmsg ); + } + } else { + unsigned long int opu = *(unsigned long int *)&op; + unsigned long int bitm = operand->bitm; + unsigned long int bitm_full = bitm | ( bitm & 1 ? 0 : 0xf ); + + if ( operand->flags & PPC_OPERAND_SIGNED ) { + bitm_full >>= 1; + + if ( ( opu & ~bitm_full ) != 0 && ( opu | bitm_full ) != -1 ) + printf( "%s: signed operand nr.%d to wide. op: %.8lx, mask: %.8lx\n", + name, argi, opu, bitm ); + } else { + if ( ( opu & ~bitm_full ) != 0 ) + printf( "%s: unsigned operand nr.%d to wide. op: %.8lx, mask: %.8lx\n", + name, argi, opu, bitm ); + } + if ( (bitm & 1) == 0 ) { + if ( opu & 0xf & ~bitm ) + printf( "%s: operand nr.%d not aligned correctly. op: %.8lx, mask: %.8lx\n", + name, argi, opu, bitm ); + } + + ret |= ( op & operand->bitm ) << operand->shift; + } + argi++; + } + if ( argc > argj ) { + printf( "Too many arguments for %s, got %d\n", name, argc ); + return ASM_ERROR_OPC; + } + + return ret; +} + + +/* + * BEGIN OF ppc-opc.c + */ + +#define ATTRIBUTE_UNUSED +#define _(x) (x) + +/* Local insertion and extraction functions. */ + +static unsigned long insert_bdm (unsigned long, long, int, const char **); +static unsigned long insert_bo (unsigned long, long, int, const char **); +static unsigned long insert_ras (unsigned long, long, int, const char **); +static unsigned long insert_rbs (unsigned long, long, int, const char **); + +/* The operands table. + + The fields are bitm, shift, insert, extract, flags. + */ + +static const struct powerpc_operand powerpc_operands[] = +{ + /* The zero index is used to indicate the end of the list of + operands. */ +#define UNUSED 0 + { 0, 0, NULL, 0 }, + + /* The BA field in an XL form instruction. */ +#define BA UNUSED + 1 + /* The BI field in a B form or XL form instruction. */ +#define BI BA +#define BI_MASK (0x1f << 16) + { 0x1f, 16, NULL, PPC_OPERAND_CR }, + + /* The BD field in a B form instruction. The lower two bits are + forced to zero. */ +#define BD BA + 1 + { 0xfffc, 0, NULL, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The BD field in a B form instruction when the - modifier is used. + This sets the y bit of the BO field appropriately. */ +#define BDM BD + 1 + { 0xfffc, 0, insert_bdm, + PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The BF field in an X or XL form instruction. */ +#define BF BDM + 1 + /* The CRFD field in an X form instruction. */ +#define CRFD BF + { 0x7, 23, NULL, PPC_OPERAND_CR }, + + /* An optional BF field. This is used for comparison instructions, + in which an omitted BF field is taken as zero. */ +#define OBF BF + 1 + { 0x7, 23, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, + + /* The BO field in a B form instruction. Certain values are + illegal. */ +#define BO OBF + 1 +#define BO_MASK (0x1f << 21) + { 0x1f, 21, insert_bo, 0 }, + + /* The condition register number portion of the BI field in a B form + or XL form instruction. This is used for the extended + conditional branch mnemonics, which set the lower two bits of the + BI field. This field is optional. */ +#define CR BO + 1 + { 0x7, 18, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, + + /* The D field in a D form instruction. This is a displacement off + a register, and implies that the next operand is a register in + parentheses. */ +#define D CR + 1 + { 0xffff, 0, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, + + /* The DS field in a DS form instruction. This is like D, but the + lower two bits are forced to zero. */ +#define DS D + 1 + { 0xfffc, 0, NULL, + PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS }, + + /* The FRA field in an X or A form instruction. */ +#define FRA DS + 1 +#define FRA_MASK (0x1f << 16) + { 0x1f, 16, NULL, PPC_OPERAND_FPR }, + + /* The FRB field in an X or A form instruction. */ +#define FRB FRA + 1 +#define FRB_MASK (0x1f << 11) + { 0x1f, 11, NULL, PPC_OPERAND_FPR }, + + /* The FRC field in an A form instruction. */ +#define FRC FRB + 1 +#define FRC_MASK (0x1f << 6) + { 0x1f, 6, NULL, PPC_OPERAND_FPR }, + + /* The FRS field in an X form instruction or the FRT field in a D, X + or A form instruction. */ +#define FRS FRC + 1 +#define FRT FRS + { 0x1f, 21, NULL, PPC_OPERAND_FPR }, + + /* The LI field in an I form instruction. The lower two bits are + forced to zero. */ +#define LI FRS + 1 + { 0x3fffffc, 0, NULL, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, + + /* The ME field in an M form instruction. */ +#define ME LI + 1 +#define ME_MASK (0x1f << 1) + { 0x1f, 1, NULL, 0 }, + + /* The MB and ME fields in an M form instruction expressed a single + operand which is a bitmask indicating which bits to select. This + is a two operand form using PPC_OPERAND_NEXT. See the + description in opcode/ppc.h for what this means. */ +#define MBE ME + 1 + { 0x1f, 6, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT }, + + /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */ +#define RA MBE + 1 +#define RA_MASK (0x1f << 16) + { 0x1f, 16, NULL, PPC_OPERAND_GPR }, + + /* As above, but 0 in the RA field means zero, not r0. */ +#define RA0 RA + 1 + { 0x1f, 16, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field in a D or X form instruction which is an updating + store or an updating floating point load, which means that the RA + field may not be zero. */ +#define RAS RA0 + 1 + { 0x1f, 16, insert_ras, PPC_OPERAND_GPR_0 }, + + /* The RB field in an X, XO, M, or MDS form instruction. */ +#define RB RAS + 1 +#define RB_MASK (0x1f << 11) + { 0x1f, 11, NULL, PPC_OPERAND_GPR }, + + /* The RB field in an X form instruction when it must be the same as + the RS field in the instruction. This is used for extended + mnemonics like mr. */ +#define RBS RB + 1 + { 0x1f, 11, insert_rbs, PPC_OPERAND_FAKE }, + + /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form + instruction or the RT field in a D, DS, X, XFX or XO form + instruction. */ +#define RS RBS + 1 +#define RT RS +#define RT_MASK (0x1f << 21) + { 0x1f, 21, NULL, PPC_OPERAND_GPR }, + + /* The SH field in an X or M form instruction. */ +#define SH RS + 1 +#define SH_MASK (0x1f << 11) + /* The other UIMM field in an EVX form instruction. */ +#define EVUIMM SH + { 0x1f, 11, NULL, 0 }, + + /* The SI field in a D form instruction. */ +#define SI SH + 1 + { 0xffff, 0, NULL, PPC_OPERAND_SIGNED }, + + /* The UI field in a D form instruction. */ +#define UI SI + 1 + { 0xffff, 0, NULL, 0 }, + +}; + + +/* The functions used to insert and extract complicated operands. */ + +/* The BD field in a B form instruction when the - modifier is used. + This modifier means that the branch is not expected to be taken. + For chips built to versions of the architecture prior to version 2 + (ie. not Power4 compatible), we set the y bit of the BO field to 1 + if the offset is negative. When extracting, we require that the y + bit be 1 and that the offset be positive, since if the y bit is 0 + we just want to print the normal form of the instruction. + Power4 compatible targets use two bits, "a", and "t", instead of + the "y" bit. "at" == 00 => no hint, "at" == 01 => unpredictable, + "at" == 10 => not taken, "at" == 11 => taken. The "t" bit is 00001 + in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000 + for branch on CTR. We only handle the taken/not-taken hint here. + Note that we don't relax the conditions tested here when + disassembling with -Many because insns using extract_bdm and + extract_bdp always occur in pairs. One or the other will always + be valid. */ + +static unsigned long +insert_bdm (unsigned long insn, + long value, + int dialect, + const char **errmsg ATTRIBUTE_UNUSED) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + if ((value & 0x8000) != 0) + insn |= 1 << 21; + } + else + { + if ((insn & (0x14 << 21)) == (0x04 << 21)) + insn |= 0x02 << 21; + else if ((insn & (0x14 << 21)) == (0x10 << 21)) + insn |= 0x08 << 21; + } + return insn | (value & 0xfffc); +} + + +/* Check for legal values of a BO field. */ + +static int +valid_bo (long value, int dialect, int extract) +{ + if ((dialect & PPC_OPCODE_POWER4) == 0) + { + int valid; + /* Certain encodings have bits that are required to be zero. + These are (z must be zero, y may be anything): + 001zy + 011zy + 1z00y + 1z01y + 1z1zz + */ + switch (value & 0x14) + { + default: + case 0: + valid = 1; + break; + case 0x4: + valid = (value & 0x2) == 0; + break; + case 0x10: + valid = (value & 0x8) == 0; + break; + case 0x14: + valid = value == 0x14; + break; + } + /* When disassembling with -Many, accept power4 encodings too. */ + if (valid + || (dialect & PPC_OPCODE_ANY) == 0 + || !extract) + return valid; + } + + /* Certain encodings have bits that are required to be zero. + These are (z must be zero, a & t may be anything): + 0000z + 0001z + 0100z + 0101z + 001at + 011at + 1a00t + 1a01t + 1z1zz + */ + if ((value & 0x14) == 0) + return (value & 0x1) == 0; + else if ((value & 0x14) == 0x14) + return value == 0x14; + else + return 1; +} + +/* The BO field in a B form instruction. Warn about attempts to set + the field to an illegal value. */ + +static unsigned long +insert_bo (unsigned long insn, + long value, + int dialect, + const char **errmsg) +{ + if (!valid_bo (value, dialect, 0)) + *errmsg = _("invalid conditional option"); + return insn | ((value & 0x1f) << 21); +} + +/* The RA field in a D or X form instruction which is an updating + store or an updating floating point load, which means that the RA + field may not be zero. */ + +static unsigned long +insert_ras (unsigned long insn, + long value, + int dialect ATTRIBUTE_UNUSED, + const char **errmsg) +{ + if (value == 0) + *errmsg = _("invalid register operand when updating"); + return insn | ((value & 0x1f) << 16); +} + +/* The RB field in an X form instruction when it must be the same as + the RS field in the instruction. This is used for extended + mnemonics like mr. This operand is marked FAKE. The insertion + function just copies the BT field into the BA field, and the + extraction function just checks that the fields are the same. */ + +static unsigned long +insert_rbs (unsigned long insn, + long value ATTRIBUTE_UNUSED, + int dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | (((insn >> 21) & 0x1f) << 11); +} + + +/* Macros used to form opcodes. */ + +/* The main opcode. */ +#define OP(x) ((((unsigned long)(x)) & 0x3f) << 26) +#define OP_MASK OP (0x3f) + +/* The main opcode combined with a trap code in the TO field of a D + form instruction. Used for extended mnemonics for the trap + instructions. */ +#define OPTO(x,to) (OP (x) | ((((unsigned long)(to)) & 0x1f) << 21)) +#define OPTO_MASK (OP_MASK | TO_MASK) + +/* The main opcode combined with a comparison size bit in the L field + of a D form or X form instruction. Used for extended mnemonics for + the comparison instructions. */ +#define OPL(x,l) (OP (x) | ((((unsigned long)(l)) & 1) << 21)) +#define OPL_MASK OPL (0x3f,1) + +/* An A form instruction. */ +#define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1)) +#define A_MASK A (0x3f, 0x1f, 1) + +/* An A_MASK with the FRB field fixed. */ +#define AFRB_MASK (A_MASK | FRB_MASK) + +/* An A_MASK with the FRC field fixed. */ +#define AFRC_MASK (A_MASK | FRC_MASK) + +/* An A_MASK with the FRA and FRC fields fixed. */ +#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK) + +/* An AFRAFRC_MASK, but with L bit clear. */ +#define AFRALFRC_MASK (AFRAFRC_MASK & ~((unsigned long) 1 << 16)) + +/* A B form instruction. */ +#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1)) +#define B_MASK B (0x3f, 1, 1) + +/* A B form instruction setting the BO field. */ +#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21)) +#define BBO_MASK BBO (0x3f, 0x1f, 1, 1) + +/* A BBO_MASK with the y bit of the BO field removed. This permits + matching a conditional branch regardless of the setting of the y + bit. Similarly for the 'at' bits used for power4 branch hints. */ +#define Y_MASK (((unsigned long) 1) << 21) +#define AT1_MASK (((unsigned long) 3) << 21) +#define AT2_MASK (((unsigned long) 9) << 21) +#define BBOY_MASK (BBO_MASK &~ Y_MASK) +#define BBOAT_MASK (BBO_MASK &~ AT1_MASK) + +/* A B form instruction setting the BO field and the condition bits of + the BI field. */ +#define BBOCB(op, bo, cb, aa, lk) \ + (BBO ((op), (bo), (aa), (lk)) | ((((unsigned long)(cb)) & 0x3) << 16)) +#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1) + +/* A BBOCB_MASK with the y bit of the BO field removed. */ +#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK) +#define BBOATCB_MASK (BBOCB_MASK &~ AT1_MASK) +#define BBOAT2CB_MASK (BBOCB_MASK &~ AT2_MASK) + +/* A BBOYCB_MASK in which the BI field is fixed. */ +#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK) +#define BBOATBI_MASK (BBOAT2CB_MASK | BI_MASK) + +/* An Context form instruction. */ +#define CTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7)) +#define CTX_MASK CTX(0x3f, 0x7) + +/* An User Context form instruction. */ +#define UCTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) +#define UCTX_MASK UCTX(0x3f, 0x1f) + +/* The main opcode mask with the RA field clear. */ +#define DRA_MASK (OP_MASK | RA_MASK) + +/* A DS form instruction. */ +#define DSO(op, xop) (OP (op) | ((xop) & 0x3)) +#define DS_MASK DSO (0x3f, 3) + +/* A DE form instruction. */ +#define DEO(op, xop) (OP (op) | ((xop) & 0xf)) +#define DE_MASK DEO (0x3e, 0xf) + +/* An EVSEL form instruction. */ +#define EVSEL(op, xop) (OP (op) | (((unsigned long)(xop)) & 0xff) << 3) +#define EVSEL_MASK EVSEL(0x3f, 0xff) + +/* An M form instruction. */ +#define M(op, rc) (OP (op) | ((rc) & 1)) +#define M_MASK M (0x3f, 1) + +/* An M form instruction with the ME field specified. */ +#define MME(op, me, rc) (M ((op), (rc)) | ((((unsigned long)(me)) & 0x1f) << 1)) + +/* An M_MASK with the MB and ME fields fixed. */ +#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK) + +/* An M_MASK with the SH and ME fields fixed. */ +#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK) + +/* An MD form instruction. */ +#define MD(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x7) << 2) | ((rc) & 1)) +#define MD_MASK MD (0x3f, 0x7, 1) + +/* An MD_MASK with the MB field fixed. */ +#define MDMB_MASK (MD_MASK | MB6_MASK) + +/* An MD_MASK with the SH field fixed. */ +#define MDSH_MASK (MD_MASK | SH6_MASK) + +/* An MDS form instruction. */ +#define MDS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0xf) << 1) | ((rc) & 1)) +#define MDS_MASK MDS (0x3f, 0xf, 1) + +/* An MDS_MASK with the MB field fixed. */ +#define MDSMB_MASK (MDS_MASK | MB6_MASK) + +/* An SC form instruction. */ +#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1)) +#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1) + +/* A VX form instruction. */ +#define VX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff)) + +/* The mask for a VX form instruction. */ +#define VX_MASK VX(0x3f, 0x7ff) + +/* A VA form instruction. */ +#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f)) + +/* The mask for a VA form instruction. */ +#define VXA_MASK VXA(0x3f, 0x3f) + +/* A VXR form instruction. */ +#define VXR(op, xop, rc) (OP (op) | (((rc) & 1) << 10) | (((unsigned long)(xop)) & 0x3ff)) + +/* The mask for a VXR form instruction. */ +#define VXR_MASK VXR(0x3f, 0x3ff, 1) + +/* An X form instruction. */ +#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) + +/* A Z form instruction. */ +#define Z(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1)) + +/* An X form instruction with the RC bit specified. */ +#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1)) + +/* A Z form instruction with the RC bit specified. */ +#define ZRC(op, xop, rc) (Z ((op), (xop)) | ((rc) & 1)) + +/* The mask for an X form instruction. */ +#define X_MASK XRC (0x3f, 0x3ff, 1) + +/* The mask for a Z form instruction. */ +#define Z_MASK ZRC (0x3f, 0x1ff, 1) +#define Z2_MASK ZRC (0x3f, 0xff, 1) + +/* An X_MASK with the RA field fixed. */ +#define XRA_MASK (X_MASK | RA_MASK) + +/* An XRA_MASK with the W field clear. */ +#define XWRA_MASK (XRA_MASK & ~((unsigned long) 1 << 16)) + +/* An X_MASK with the RB field fixed. */ +#define XRB_MASK (X_MASK | RB_MASK) + +/* An X_MASK with the RT field fixed. */ +#define XRT_MASK (X_MASK | RT_MASK) + +/* An XRT_MASK mask with the L bits clear. */ +#define XLRT_MASK (XRT_MASK & ~((unsigned long) 0x3 << 21)) + +/* An X_MASK with the RA and RB fields fixed. */ +#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) + +/* An XRARB_MASK, but with the L bit clear. */ +#define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16)) + +/* An X_MASK with the RT and RA fields fixed. */ +#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK) + +/* An XRTRA_MASK, but with L bit clear. */ +#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21)) + +/* An X form instruction with the L bit specified. */ +#define XOPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21)) + +/* The mask for an X form comparison instruction. */ +#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22)) + +/* The mask for an X form comparison instruction with the L field + fixed. */ +#define XCMPL_MASK (XCMP_MASK | (((unsigned long)1) << 21)) + +/* An X form trap instruction with the TO field specified. */ +#define XTO(op, xop, to) (X ((op), (xop)) | ((((unsigned long)(to)) & 0x1f) << 21)) +#define XTO_MASK (X_MASK | TO_MASK) + +/* An X form tlb instruction with the SH field specified. */ +#define XTLB(op, xop, sh) (X ((op), (xop)) | ((((unsigned long)(sh)) & 0x1f) << 11)) +#define XTLB_MASK (X_MASK | SH_MASK) + +/* An X form sync instruction. */ +#define XSYNC(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 3) << 21)) + +/* An X form sync instruction with everything filled in except the LS field. */ +#define XSYNC_MASK (0xff9fffff) + +/* An X_MASK, but with the EH bit clear. */ +#define XEH_MASK (X_MASK & ~((unsigned long )1)) + +/* An X form AltiVec dss instruction. */ +#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25)) +#define XDSS_MASK XDSS(0x3f, 0x3ff, 1) + +/* An XFL form instruction. */ +#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1)) +#define XFL_MASK XFL (0x3f, 0x3ff, 1) + +/* An X form isel instruction. */ +#define XISEL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1)) +#define XISEL_MASK XISEL(0x3f, 0x1f) + +/* An XL form instruction with the LK field set to 0. */ +#define XL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) + +/* An XL form instruction which uses the LK field. */ +#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1)) + +/* The mask for an XL form instruction. */ +#define XL_MASK XLLK (0x3f, 0x3ff, 1) + +/* An XL form instruction which explicitly sets the BO field. */ +#define XLO(op, bo, xop, lk) \ + (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21)) +#define XLO_MASK (XL_MASK | BO_MASK) + +/* An XL form instruction which explicitly sets the y bit of the BO + field. */ +#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | ((((unsigned long)(y)) & 1) << 21)) +#define XLYLK_MASK (XL_MASK | Y_MASK) + +/* An XL form instruction which sets the BO field and the condition + bits of the BI field. */ +#define XLOCB(op, bo, cb, xop, lk) \ + (XLO ((op), (bo), (xop), (lk)) | ((((unsigned long)(cb)) & 3) << 16)) +#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1) + +#define BB_MASK (0x1f << 11) +/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */ +#define XLBB_MASK (XL_MASK | BB_MASK) +#define XLYBB_MASK (XLYLK_MASK | BB_MASK) +#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK) + +/* A mask for branch instructions using the BH field. */ +#define XLBH_MASK (XL_MASK | (0x1c << 11)) + +/* An XL_MASK with the BO and BB fields fixed. */ +#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK) + +/* An XL_MASK with the BO, BI and BB fields fixed. */ +#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK) + +/* An XO form instruction. */ +#define XO(op, xop, oe, rc) \ + (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1)) +#define XO_MASK XO (0x3f, 0x1ff, 1, 1) + +/* An XO_MASK with the RB field fixed. */ +#define XORB_MASK (XO_MASK | RB_MASK) + +/* An XS form instruction. */ +#define XS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 2) | (((unsigned long)(rc)) & 1)) +#define XS_MASK XS (0x3f, 0x1ff, 1) + +/* A mask for the FXM version of an XFX form instruction. */ +#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20)) + +/* An XFX form instruction with the FXM field filled in. */ +#define XFXM(op, xop, fxm, p4) \ + (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \ + | ((unsigned long)(p4) << 20)) + +#define SPR_MASK (0x3ff << 11) +/* An XFX form instruction with the SPR field filled in. */ +#define XSPR(op, xop, spr) \ + (X ((op), (xop)) | ((((unsigned long)(spr)) & 0x1f) << 16) | ((((unsigned long)(spr)) & 0x3e0) << 6)) +#define XSPR_MASK (X_MASK | SPR_MASK) + +/* An XFX form instruction with the SPR field filled in except for the + SPRBAT field. */ +#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK) + +/* An XFX form instruction with the SPR field filled in except for the + SPRG field. */ +#define XSPRG_MASK (XSPR_MASK & ~(0x1f << 16)) + +/* An X form instruction with everything filled in except the E field. */ +#define XE_MASK (0xffff7fff) + +/* An X form user context instruction. */ +#define XUC(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) +#define XUC_MASK XUC(0x3f, 0x1f) + +/* The BO encodings used in extended conditional branch mnemonics. */ +#define BODNZF (0x0) +#define BODNZFP (0x1) +#define BODZF (0x2) +#define BODZFP (0x3) +#define BODNZT (0x8) +#define BODNZTP (0x9) +#define BODZT (0xa) +#define BODZTP (0xb) + +#define BOF (0x4) +#define BOFP (0x5) +#define BOFM4 (0x6) +#define BOFP4 (0x7) +#define BOT (0xc) +#define BOTP (0xd) +#define BOTM4 (0xe) +#define BOTP4 (0xf) + +#define BODNZ (0x10) +#define BODNZP (0x11) +#define BODZ (0x12) +#define BODZP (0x13) +#define BODNZM4 (0x18) +#define BODNZP4 (0x19) +#define BODZM4 (0x1a) +#define BODZP4 (0x1b) + +#define BOU (0x14) + +/* The BI condition bit encodings used in extended conditional branch + mnemonics. */ +#define CBLT (0) +#define CBGT (1) +#define CBEQ (2) +#define CBSO (3) + +/* The TO encodings used in extended trap mnemonics. */ +#define TOLGT (0x1) +#define TOLLT (0x2) +#define TOEQ (0x4) +#define TOLGE (0x5) +#define TOLNL (0x5) +#define TOLLE (0x6) +#define TOLNG (0x6) +#define TOGT (0x8) +#define TOGE (0xc) +#define TONL (0xc) +#define TOLT (0x10) +#define TOLE (0x14) +#define TONG (0x14) +#define TONE (0x18) +#define TOU (0x1f) + +/* Smaller names for the flags so each entry in the opcodes table will + fit on a single line. */ +#undef PPC +#define PPC PPC_OPCODE_PPC +#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON +#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC +#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON +#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32 + +/* The opcode table. + + The format of the opcode table is: + + NAME OPCODE MASK FLAGS { OPERANDS } + + NAME is the name of the instruction. + OPCODE is the instruction opcode. + MASK is the opcode mask; this is used to tell the disassembler + which bits in the actual opcode must match OPCODE. + FLAGS are flags indicated what processors support the instruction. + OPERANDS is the list of operands. + + The disassembler reads the table in order and prints the first + instruction which matches, so this table is sorted to put more + specific instructions before more general instructions. It is also + sorted by major opcode. */ + +static const struct powerpc_opcode powerpc_opcodes[] = { + +{ "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI } }, +{ "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI } }, +{ "cmpw", XOPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, +{ "cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, +{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, + +{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } }, +{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SI } }, + +{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA0, SI } }, +{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA0,SI } }, +{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM } }, +{ "bc", B(16,0,0), B_MASK, COM, { BO, BI, BD } }, +{ "bcl", B(16,0,1), B_MASK, COM, { BO, BI, BD } }, +{ "b", B(18,0,0), B_MASK, COM, { LI } }, +{ "bl", B(18,0,1), B_MASK, COM, { LI } }, +{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } }, +{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } }, +{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } }, + +{ "rlwinm", M(21,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } }, +{ "nop", OP(24), 0xffffffff, PPCCOM, { 0 } }, +{ "ori", OP(24), OP_MASK, PPCCOM, { RA, RS, UI } }, +{ "xoris", OP(27), OP_MASK, PPCCOM, { RA, RS, UI } }, +{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA0, RB } }, +{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA0, RB } }, +{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } }, +{ "and", XRC(31,28,0), X_MASK, COM, { RA, RS, RB } }, +{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA } }, +{ "lbzx", X(31,87), X_MASK, COM, { RT, RA0, RB } }, +{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } }, +{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } }, +{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA0, RB } }, +{ "stbx", X(31,215), X_MASK, COM, { RS, RA0, RB } }, +{ "mullw", XO(31,235,0,0), XO_MASK, PPCCOM, { RT, RA, RB } }, +{ "add", XO(31,266,0,0), XO_MASK, PPCCOM, { RT, RA, RB } }, +{ "lhzx", X(31,279), X_MASK, COM, { RT, RA0, RB } }, +{ "xor", XRC(31,316,0), X_MASK, COM, { RA, RS, RB } }, +{ "mflr", XSPR(31,339,8), XSPR_MASK, COM, { RT } }, +{ "sthx", X(31,407), X_MASK, COM, { RS, RA0, RB } }, +{ "mr", XRC(31,444,0), X_MASK, COM, { RA, RS, RBS } }, +{ "or", XRC(31,444,0), X_MASK, COM, { RA, RS, RB } }, +{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB } }, +{ "mtlr", XSPR(31,467,8), XSPR_MASK, COM, { RS } }, +{ "mtctr", XSPR(31,467,9), XSPR_MASK, COM, { RS } }, +{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB } }, +{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA0, RB } }, +{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } }, +{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA0, RB } }, +{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } }, +{ "extsh", XRC(31,922,0), XRB_MASK, PPCCOM, { RA, RS } }, +{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS} }, + +{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA0 } }, +{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA0 } }, +{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA0 } }, +{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } }, +{ "stb", OP(38), OP_MASK, COM, { RS, D, RA0 } }, +{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA0 } }, +{ "sth", OP(44), OP_MASK, COM, { RS, D, RA0 } }, +{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA0 } }, +{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA0 } }, +{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA0 } }, +{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA0 } }, +{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA0 } }, + +{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, +{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, +{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, +{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } }, +{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA0 } }, +{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } }, +{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } }, +{ "fctiwz", XRC(63,15,0), XRA_MASK, PPCCOM, { FRT, FRB } }, +{ "fsub", A(63,20,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } }, +{ "fneg", XRC(63,40,0), XRA_MASK, COM, { FRT, FRB } }, +}; /* * VM_TIMES enables showing information about time spent inside diff --git a/code/qcommon/vm_powerpc_asm.c b/code/qcommon/vm_powerpc_asm.c deleted file mode 100644 index 5ad62a3b..00000000 --- a/code/qcommon/vm_powerpc_asm.c +++ /dev/null @@ -1,1003 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2008 Przemyslaw Iskra - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== - - * File includes code from GNU binutils, exactly: - * - include/opcode/ppc.h - licensed under GPL v1 or later - * - opcodes/ppc-opc.c - licensed under GPL v2 or later - * - * ppc.h -- Header file for PowerPC opcode table - * Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. - * Written by Ian Lance Taylor, Cygnus Suppor - * - * This file is part of GDB, GAS, and the GNU binutils. - * - * ppc-opc.c -- PowerPC opcode list - * Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, - * 2005, 2006, 2007 Free Software Foundation, Inc. - * Written by Ian Lance Taylor, Cygnus Support - * - * This file is part of GDB, GAS, and the GNU binutils. - * - */ - -#include "vm_local.h" -#include "vm_powerpc_asm.h" - -#include -#include -#include - -/* return nop on error */ -#define ASM_ERROR_OPC (0x60000000) - -/* - * BEGIN OF ppc.h - */ - -#define ppc_cpu_t int - -struct powerpc_opcode -{ - const char *name; - unsigned long opcode; - unsigned long mask; - ppc_cpu_t flags; - unsigned char operands[8]; -}; - -static const struct powerpc_opcode powerpc_opcodes[]; - -#define PPC_OPCODE_PPC 1 -#define PPC_OPCODE_POWER 2 -#define PPC_OPCODE_POWER2 4 -#define PPC_OPCODE_32 8 -#define PPC_OPCODE_64 0x10 -#define PPC_OPCODE_601 0x20 -#define PPC_OPCODE_COMMON 0x40 -#define PPC_OPCODE_ANY 0x80 -#define PPC_OPCODE_64_BRIDGE 0x100 -#define PPC_OPCODE_ALTIVEC 0x200 -#define PPC_OPCODE_403 0x400 -#define PPC_OPCODE_BOOKE 0x800 -#define PPC_OPCODE_BOOKE64 0x1000 -#define PPC_OPCODE_440 0x2000 -#define PPC_OPCODE_POWER4 0x4000 -#define PPC_OPCODE_NOPOWER4 0x8000 -#define PPC_OPCODE_CLASSIC 0x10000 -#define PPC_OPCODE_SPE 0x20000 -#define PPC_OPCODE_ISEL 0x40000 -#define PPC_OPCODE_EFS 0x80000 -#define PPC_OPCODE_BRLOCK 0x100000 -#define PPC_OPCODE_PMR 0x200000 -#define PPC_OPCODE_CACHELCK 0x400000 -#define PPC_OPCODE_RFMCI 0x800000 -#define PPC_OPCODE_POWER5 0x1000000 -#define PPC_OPCODE_E300 0x2000000 -#define PPC_OPCODE_POWER6 0x4000000 -#define PPC_OPCODE_CELL 0x8000000 -#define PPC_OPCODE_PPCPS 0x10000000 -#define PPC_OPCODE_E500MC 0x20000000 -#define PPC_OPCODE_405 0x40000000 -#define PPC_OPCODE_VSX 0x80000000 - -#define PPC_OP(i) (((i) >> 26) & 0x3f) - -struct powerpc_operand -{ - unsigned int bitm; - int shift; - unsigned long (*insert) - (unsigned long, long, int, const char **); - unsigned long flags; -}; - -static const struct powerpc_operand powerpc_operands[]; - -#define PPC_OPERAND_SIGNED (0x1) -#define PPC_OPERAND_SIGNOPT (0x2) -#define PPC_OPERAND_FAKE (0x4) -#define PPC_OPERAND_PARENS (0x8) -#define PPC_OPERAND_CR (0x10) -#define PPC_OPERAND_GPR (0x20) -#define PPC_OPERAND_GPR_0 (0x40) -#define PPC_OPERAND_FPR (0x80) -#define PPC_OPERAND_RELATIVE (0x100) -#define PPC_OPERAND_ABSOLUTE (0x200) -#define PPC_OPERAND_OPTIONAL (0x400) -#define PPC_OPERAND_NEXT (0x800) -#define PPC_OPERAND_NEGATIVE (0x1000) -#define PPC_OPERAND_VR (0x2000) -#define PPC_OPERAND_DS (0x4000) -#define PPC_OPERAND_DQ (0x8000) -#define PPC_OPERAND_PLUS1 (0x10000) -#define PPC_OPERAND_FSL (0x20000) -#define PPC_OPERAND_FCR (0x40000) -#define PPC_OPERAND_UDI (0x80000) -#define PPC_OPERAND_VSR (0x100000) - -/* - * END OF ppc.h - */ - -#define PPC_DEST_ARCH PPC_OPCODE_PPC - -ppc_instruction_t -asm_instruction( powerpc_iname_t sname, const int argc, const long int *argv ) -{ - const char *errmsg = NULL; - const char *name; - unsigned long int ret; - const struct powerpc_opcode *opcode = NULL; - int argi, argj; - - opcode = &powerpc_opcodes[ sname ]; - name = opcode->name; - - if ( ! opcode ) { - printf( "Can't find opcode %d\n", sname ); - return ASM_ERROR_OPC; - } - if ( ( opcode->flags & PPC_DEST_ARCH ) != PPC_DEST_ARCH ) { - printf( "opcode %s not defined for this arch\n", name ); - return ASM_ERROR_OPC; - } - - ret = opcode->opcode; - - argi = argj = 0; - while ( opcode->operands[ argi ] != 0 ) { - long int op = 0; - const struct powerpc_operand *operand = &powerpc_operands[ opcode->operands[ argi ] ]; - - if ( ! (operand->flags & PPC_OPERAND_FAKE) ) { - if ( argj >= argc ) { - printf( "Not enough arguments for %s, got %d\n", name, argc ); - return ASM_ERROR_OPC; - } - - op = argv[ argj++ ]; - } - - if ( operand->insert ) { - errmsg = NULL; - ret = operand->insert( ret, op, PPC_DEST_ARCH, &errmsg ); - if ( errmsg ) { - printf( "%s: error while inserting operand %d (0x%.2lx): %s\n", - name, argi, op, errmsg ); - } - } else { - unsigned long int opu = *(unsigned long int *)&op; - unsigned long int bitm = operand->bitm; - unsigned long int bitm_full = bitm | ( bitm & 1 ? 0 : 0xf ); - - if ( operand->flags & PPC_OPERAND_SIGNED ) { - bitm_full >>= 1; - - if ( ( opu & ~bitm_full ) != 0 && ( opu | bitm_full ) != -1 ) - printf( "%s: signed operand nr.%d to wide. op: %.8lx, mask: %.8lx\n", - name, argi, opu, bitm ); - } else { - if ( ( opu & ~bitm_full ) != 0 ) - printf( "%s: unsigned operand nr.%d to wide. op: %.8lx, mask: %.8lx\n", - name, argi, opu, bitm ); - } - if ( (bitm & 1) == 0 ) { - if ( opu & 0xf & ~bitm ) - printf( "%s: operand nr.%d not aligned correctly. op: %.8lx, mask: %.8lx\n", - name, argi, opu, bitm ); - } - - ret |= ( op & operand->bitm ) << operand->shift; - } - argi++; - } - if ( argc > argj ) { - printf( "Too many arguments for %s, got %d\n", name, argc ); - return ASM_ERROR_OPC; - } - - return ret; -} - - -/* - * BEGIN OF ppc-opc.c - */ - -#define ATTRIBUTE_UNUSED -#define _(x) (x) - -/* Local insertion and extraction functions. */ - -static unsigned long insert_bdm (unsigned long, long, int, const char **); -static unsigned long insert_bo (unsigned long, long, int, const char **); -static unsigned long insert_ras (unsigned long, long, int, const char **); -static unsigned long insert_rbs (unsigned long, long, int, const char **); - -/* The operands table. - - The fields are bitm, shift, insert, extract, flags. - */ - -static const struct powerpc_operand powerpc_operands[] = -{ - /* The zero index is used to indicate the end of the list of - operands. */ -#define UNUSED 0 - { 0, 0, NULL, 0 }, - - /* The BA field in an XL form instruction. */ -#define BA UNUSED + 1 - /* The BI field in a B form or XL form instruction. */ -#define BI BA -#define BI_MASK (0x1f << 16) - { 0x1f, 16, NULL, PPC_OPERAND_CR }, - - /* The BD field in a B form instruction. The lower two bits are - forced to zero. */ -#define BD BA + 1 - { 0xfffc, 0, NULL, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, - - /* The BD field in a B form instruction when the - modifier is used. - This sets the y bit of the BO field appropriately. */ -#define BDM BD + 1 - { 0xfffc, 0, insert_bdm, - PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, - - /* The BF field in an X or XL form instruction. */ -#define BF BDM + 1 - /* The CRFD field in an X form instruction. */ -#define CRFD BF - { 0x7, 23, NULL, PPC_OPERAND_CR }, - - /* An optional BF field. This is used for comparison instructions, - in which an omitted BF field is taken as zero. */ -#define OBF BF + 1 - { 0x7, 23, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, - - /* The BO field in a B form instruction. Certain values are - illegal. */ -#define BO OBF + 1 -#define BO_MASK (0x1f << 21) - { 0x1f, 21, insert_bo, 0 }, - - /* The condition register number portion of the BI field in a B form - or XL form instruction. This is used for the extended - conditional branch mnemonics, which set the lower two bits of the - BI field. This field is optional. */ -#define CR BO + 1 - { 0x7, 18, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, - - /* The D field in a D form instruction. This is a displacement off - a register, and implies that the next operand is a register in - parentheses. */ -#define D CR + 1 - { 0xffff, 0, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, - - /* The DS field in a DS form instruction. This is like D, but the - lower two bits are forced to zero. */ -#define DS D + 1 - { 0xfffc, 0, NULL, - PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS }, - - /* The FRA field in an X or A form instruction. */ -#define FRA DS + 1 -#define FRA_MASK (0x1f << 16) - { 0x1f, 16, NULL, PPC_OPERAND_FPR }, - - /* The FRB field in an X or A form instruction. */ -#define FRB FRA + 1 -#define FRB_MASK (0x1f << 11) - { 0x1f, 11, NULL, PPC_OPERAND_FPR }, - - /* The FRC field in an A form instruction. */ -#define FRC FRB + 1 -#define FRC_MASK (0x1f << 6) - { 0x1f, 6, NULL, PPC_OPERAND_FPR }, - - /* The FRS field in an X form instruction or the FRT field in a D, X - or A form instruction. */ -#define FRS FRC + 1 -#define FRT FRS - { 0x1f, 21, NULL, PPC_OPERAND_FPR }, - - /* The LI field in an I form instruction. The lower two bits are - forced to zero. */ -#define LI FRS + 1 - { 0x3fffffc, 0, NULL, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED }, - - /* The ME field in an M form instruction. */ -#define ME LI + 1 -#define ME_MASK (0x1f << 1) - { 0x1f, 1, NULL, 0 }, - - /* The MB and ME fields in an M form instruction expressed a single - operand which is a bitmask indicating which bits to select. This - is a two operand form using PPC_OPERAND_NEXT. See the - description in opcode/ppc.h for what this means. */ -#define MBE ME + 1 - { 0x1f, 6, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT }, - - /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */ -#define RA MBE + 1 -#define RA_MASK (0x1f << 16) - { 0x1f, 16, NULL, PPC_OPERAND_GPR }, - - /* As above, but 0 in the RA field means zero, not r0. */ -#define RA0 RA + 1 - { 0x1f, 16, NULL, PPC_OPERAND_GPR_0 }, - - /* The RA field in a D or X form instruction which is an updating - store or an updating floating point load, which means that the RA - field may not be zero. */ -#define RAS RA0 + 1 - { 0x1f, 16, insert_ras, PPC_OPERAND_GPR_0 }, - - /* The RB field in an X, XO, M, or MDS form instruction. */ -#define RB RAS + 1 -#define RB_MASK (0x1f << 11) - { 0x1f, 11, NULL, PPC_OPERAND_GPR }, - - /* The RB field in an X form instruction when it must be the same as - the RS field in the instruction. This is used for extended - mnemonics like mr. */ -#define RBS RB + 1 - { 0x1f, 11, insert_rbs, PPC_OPERAND_FAKE }, - - /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form - instruction or the RT field in a D, DS, X, XFX or XO form - instruction. */ -#define RS RBS + 1 -#define RT RS -#define RT_MASK (0x1f << 21) - { 0x1f, 21, NULL, PPC_OPERAND_GPR }, - - /* The SH field in an X or M form instruction. */ -#define SH RS + 1 -#define SH_MASK (0x1f << 11) - /* The other UIMM field in an EVX form instruction. */ -#define EVUIMM SH - { 0x1f, 11, NULL, 0 }, - - /* The SI field in a D form instruction. */ -#define SI SH + 1 - { 0xffff, 0, NULL, PPC_OPERAND_SIGNED }, - - /* The UI field in a D form instruction. */ -#define UI SI + 1 - { 0xffff, 0, NULL, 0 }, - -}; - - -/* The functions used to insert and extract complicated operands. */ - -/* The BD field in a B form instruction when the - modifier is used. - This modifier means that the branch is not expected to be taken. - For chips built to versions of the architecture prior to version 2 - (ie. not Power4 compatible), we set the y bit of the BO field to 1 - if the offset is negative. When extracting, we require that the y - bit be 1 and that the offset be positive, since if the y bit is 0 - we just want to print the normal form of the instruction. - Power4 compatible targets use two bits, "a", and "t", instead of - the "y" bit. "at" == 00 => no hint, "at" == 01 => unpredictable, - "at" == 10 => not taken, "at" == 11 => taken. The "t" bit is 00001 - in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000 - for branch on CTR. We only handle the taken/not-taken hint here. - Note that we don't relax the conditions tested here when - disassembling with -Many because insns using extract_bdm and - extract_bdp always occur in pairs. One or the other will always - be valid. */ - -static unsigned long -insert_bdm (unsigned long insn, - long value, - int dialect, - const char **errmsg ATTRIBUTE_UNUSED) -{ - if ((dialect & PPC_OPCODE_POWER4) == 0) - { - if ((value & 0x8000) != 0) - insn |= 1 << 21; - } - else - { - if ((insn & (0x14 << 21)) == (0x04 << 21)) - insn |= 0x02 << 21; - else if ((insn & (0x14 << 21)) == (0x10 << 21)) - insn |= 0x08 << 21; - } - return insn | (value & 0xfffc); -} - - -/* Check for legal values of a BO field. */ - -static int -valid_bo (long value, int dialect, int extract) -{ - if ((dialect & PPC_OPCODE_POWER4) == 0) - { - int valid; - /* Certain encodings have bits that are required to be zero. - These are (z must be zero, y may be anything): - 001zy - 011zy - 1z00y - 1z01y - 1z1zz - */ - switch (value & 0x14) - { - default: - case 0: - valid = 1; - break; - case 0x4: - valid = (value & 0x2) == 0; - break; - case 0x10: - valid = (value & 0x8) == 0; - break; - case 0x14: - valid = value == 0x14; - break; - } - /* When disassembling with -Many, accept power4 encodings too. */ - if (valid - || (dialect & PPC_OPCODE_ANY) == 0 - || !extract) - return valid; - } - - /* Certain encodings have bits that are required to be zero. - These are (z must be zero, a & t may be anything): - 0000z - 0001z - 0100z - 0101z - 001at - 011at - 1a00t - 1a01t - 1z1zz - */ - if ((value & 0x14) == 0) - return (value & 0x1) == 0; - else if ((value & 0x14) == 0x14) - return value == 0x14; - else - return 1; -} - -/* The BO field in a B form instruction. Warn about attempts to set - the field to an illegal value. */ - -static unsigned long -insert_bo (unsigned long insn, - long value, - int dialect, - const char **errmsg) -{ - if (!valid_bo (value, dialect, 0)) - *errmsg = _("invalid conditional option"); - return insn | ((value & 0x1f) << 21); -} - -/* The RA field in a D or X form instruction which is an updating - store or an updating floating point load, which means that the RA - field may not be zero. */ - -static unsigned long -insert_ras (unsigned long insn, - long value, - int dialect ATTRIBUTE_UNUSED, - const char **errmsg) -{ - if (value == 0) - *errmsg = _("invalid register operand when updating"); - return insn | ((value & 0x1f) << 16); -} - -/* The RB field in an X form instruction when it must be the same as - the RS field in the instruction. This is used for extended - mnemonics like mr. This operand is marked FAKE. The insertion - function just copies the BT field into the BA field, and the - extraction function just checks that the fields are the same. */ - -static unsigned long -insert_rbs (unsigned long insn, - long value ATTRIBUTE_UNUSED, - int dialect ATTRIBUTE_UNUSED, - const char **errmsg ATTRIBUTE_UNUSED) -{ - return insn | (((insn >> 21) & 0x1f) << 11); -} - - -/* Macros used to form opcodes. */ - -/* The main opcode. */ -#define OP(x) ((((unsigned long)(x)) & 0x3f) << 26) -#define OP_MASK OP (0x3f) - -/* The main opcode combined with a trap code in the TO field of a D - form instruction. Used for extended mnemonics for the trap - instructions. */ -#define OPTO(x,to) (OP (x) | ((((unsigned long)(to)) & 0x1f) << 21)) -#define OPTO_MASK (OP_MASK | TO_MASK) - -/* The main opcode combined with a comparison size bit in the L field - of a D form or X form instruction. Used for extended mnemonics for - the comparison instructions. */ -#define OPL(x,l) (OP (x) | ((((unsigned long)(l)) & 1) << 21)) -#define OPL_MASK OPL (0x3f,1) - -/* An A form instruction. */ -#define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1)) -#define A_MASK A (0x3f, 0x1f, 1) - -/* An A_MASK with the FRB field fixed. */ -#define AFRB_MASK (A_MASK | FRB_MASK) - -/* An A_MASK with the FRC field fixed. */ -#define AFRC_MASK (A_MASK | FRC_MASK) - -/* An A_MASK with the FRA and FRC fields fixed. */ -#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK) - -/* An AFRAFRC_MASK, but with L bit clear. */ -#define AFRALFRC_MASK (AFRAFRC_MASK & ~((unsigned long) 1 << 16)) - -/* A B form instruction. */ -#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1)) -#define B_MASK B (0x3f, 1, 1) - -/* A B form instruction setting the BO field. */ -#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21)) -#define BBO_MASK BBO (0x3f, 0x1f, 1, 1) - -/* A BBO_MASK with the y bit of the BO field removed. This permits - matching a conditional branch regardless of the setting of the y - bit. Similarly for the 'at' bits used for power4 branch hints. */ -#define Y_MASK (((unsigned long) 1) << 21) -#define AT1_MASK (((unsigned long) 3) << 21) -#define AT2_MASK (((unsigned long) 9) << 21) -#define BBOY_MASK (BBO_MASK &~ Y_MASK) -#define BBOAT_MASK (BBO_MASK &~ AT1_MASK) - -/* A B form instruction setting the BO field and the condition bits of - the BI field. */ -#define BBOCB(op, bo, cb, aa, lk) \ - (BBO ((op), (bo), (aa), (lk)) | ((((unsigned long)(cb)) & 0x3) << 16)) -#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1) - -/* A BBOCB_MASK with the y bit of the BO field removed. */ -#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK) -#define BBOATCB_MASK (BBOCB_MASK &~ AT1_MASK) -#define BBOAT2CB_MASK (BBOCB_MASK &~ AT2_MASK) - -/* A BBOYCB_MASK in which the BI field is fixed. */ -#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK) -#define BBOATBI_MASK (BBOAT2CB_MASK | BI_MASK) - -/* An Context form instruction. */ -#define CTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7)) -#define CTX_MASK CTX(0x3f, 0x7) - -/* An User Context form instruction. */ -#define UCTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) -#define UCTX_MASK UCTX(0x3f, 0x1f) - -/* The main opcode mask with the RA field clear. */ -#define DRA_MASK (OP_MASK | RA_MASK) - -/* A DS form instruction. */ -#define DSO(op, xop) (OP (op) | ((xop) & 0x3)) -#define DS_MASK DSO (0x3f, 3) - -/* A DE form instruction. */ -#define DEO(op, xop) (OP (op) | ((xop) & 0xf)) -#define DE_MASK DEO (0x3e, 0xf) - -/* An EVSEL form instruction. */ -#define EVSEL(op, xop) (OP (op) | (((unsigned long)(xop)) & 0xff) << 3) -#define EVSEL_MASK EVSEL(0x3f, 0xff) - -/* An M form instruction. */ -#define M(op, rc) (OP (op) | ((rc) & 1)) -#define M_MASK M (0x3f, 1) - -/* An M form instruction with the ME field specified. */ -#define MME(op, me, rc) (M ((op), (rc)) | ((((unsigned long)(me)) & 0x1f) << 1)) - -/* An M_MASK with the MB and ME fields fixed. */ -#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK) - -/* An M_MASK with the SH and ME fields fixed. */ -#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK) - -/* An MD form instruction. */ -#define MD(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x7) << 2) | ((rc) & 1)) -#define MD_MASK MD (0x3f, 0x7, 1) - -/* An MD_MASK with the MB field fixed. */ -#define MDMB_MASK (MD_MASK | MB6_MASK) - -/* An MD_MASK with the SH field fixed. */ -#define MDSH_MASK (MD_MASK | SH6_MASK) - -/* An MDS form instruction. */ -#define MDS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0xf) << 1) | ((rc) & 1)) -#define MDS_MASK MDS (0x3f, 0xf, 1) - -/* An MDS_MASK with the MB field fixed. */ -#define MDSMB_MASK (MDS_MASK | MB6_MASK) - -/* An SC form instruction. */ -#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1)) -#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1) - -/* A VX form instruction. */ -#define VX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff)) - -/* The mask for a VX form instruction. */ -#define VX_MASK VX(0x3f, 0x7ff) - -/* A VA form instruction. */ -#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f)) - -/* The mask for a VA form instruction. */ -#define VXA_MASK VXA(0x3f, 0x3f) - -/* A VXR form instruction. */ -#define VXR(op, xop, rc) (OP (op) | (((rc) & 1) << 10) | (((unsigned long)(xop)) & 0x3ff)) - -/* The mask for a VXR form instruction. */ -#define VXR_MASK VXR(0x3f, 0x3ff, 1) - -/* An X form instruction. */ -#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) - -/* A Z form instruction. */ -#define Z(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1)) - -/* An X form instruction with the RC bit specified. */ -#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1)) - -/* A Z form instruction with the RC bit specified. */ -#define ZRC(op, xop, rc) (Z ((op), (xop)) | ((rc) & 1)) - -/* The mask for an X form instruction. */ -#define X_MASK XRC (0x3f, 0x3ff, 1) - -/* The mask for a Z form instruction. */ -#define Z_MASK ZRC (0x3f, 0x1ff, 1) -#define Z2_MASK ZRC (0x3f, 0xff, 1) - -/* An X_MASK with the RA field fixed. */ -#define XRA_MASK (X_MASK | RA_MASK) - -/* An XRA_MASK with the W field clear. */ -#define XWRA_MASK (XRA_MASK & ~((unsigned long) 1 << 16)) - -/* An X_MASK with the RB field fixed. */ -#define XRB_MASK (X_MASK | RB_MASK) - -/* An X_MASK with the RT field fixed. */ -#define XRT_MASK (X_MASK | RT_MASK) - -/* An XRT_MASK mask with the L bits clear. */ -#define XLRT_MASK (XRT_MASK & ~((unsigned long) 0x3 << 21)) - -/* An X_MASK with the RA and RB fields fixed. */ -#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) - -/* An XRARB_MASK, but with the L bit clear. */ -#define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16)) - -/* An X_MASK with the RT and RA fields fixed. */ -#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK) - -/* An XRTRA_MASK, but with L bit clear. */ -#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21)) - -/* An X form instruction with the L bit specified. */ -#define XOPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21)) - -/* The mask for an X form comparison instruction. */ -#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22)) - -/* The mask for an X form comparison instruction with the L field - fixed. */ -#define XCMPL_MASK (XCMP_MASK | (((unsigned long)1) << 21)) - -/* An X form trap instruction with the TO field specified. */ -#define XTO(op, xop, to) (X ((op), (xop)) | ((((unsigned long)(to)) & 0x1f) << 21)) -#define XTO_MASK (X_MASK | TO_MASK) - -/* An X form tlb instruction with the SH field specified. */ -#define XTLB(op, xop, sh) (X ((op), (xop)) | ((((unsigned long)(sh)) & 0x1f) << 11)) -#define XTLB_MASK (X_MASK | SH_MASK) - -/* An X form sync instruction. */ -#define XSYNC(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 3) << 21)) - -/* An X form sync instruction with everything filled in except the LS field. */ -#define XSYNC_MASK (0xff9fffff) - -/* An X_MASK, but with the EH bit clear. */ -#define XEH_MASK (X_MASK & ~((unsigned long )1)) - -/* An X form AltiVec dss instruction. */ -#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25)) -#define XDSS_MASK XDSS(0x3f, 0x3ff, 1) - -/* An XFL form instruction. */ -#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1)) -#define XFL_MASK XFL (0x3f, 0x3ff, 1) - -/* An X form isel instruction. */ -#define XISEL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1)) -#define XISEL_MASK XISEL(0x3f, 0x1f) - -/* An XL form instruction with the LK field set to 0. */ -#define XL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) - -/* An XL form instruction which uses the LK field. */ -#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1)) - -/* The mask for an XL form instruction. */ -#define XL_MASK XLLK (0x3f, 0x3ff, 1) - -/* An XL form instruction which explicitly sets the BO field. */ -#define XLO(op, bo, xop, lk) \ - (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21)) -#define XLO_MASK (XL_MASK | BO_MASK) - -/* An XL form instruction which explicitly sets the y bit of the BO - field. */ -#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | ((((unsigned long)(y)) & 1) << 21)) -#define XLYLK_MASK (XL_MASK | Y_MASK) - -/* An XL form instruction which sets the BO field and the condition - bits of the BI field. */ -#define XLOCB(op, bo, cb, xop, lk) \ - (XLO ((op), (bo), (xop), (lk)) | ((((unsigned long)(cb)) & 3) << 16)) -#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1) - -#define BB_MASK (0x1f << 11) -/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */ -#define XLBB_MASK (XL_MASK | BB_MASK) -#define XLYBB_MASK (XLYLK_MASK | BB_MASK) -#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK) - -/* A mask for branch instructions using the BH field. */ -#define XLBH_MASK (XL_MASK | (0x1c << 11)) - -/* An XL_MASK with the BO and BB fields fixed. */ -#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK) - -/* An XL_MASK with the BO, BI and BB fields fixed. */ -#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK) - -/* An XO form instruction. */ -#define XO(op, xop, oe, rc) \ - (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1)) -#define XO_MASK XO (0x3f, 0x1ff, 1, 1) - -/* An XO_MASK with the RB field fixed. */ -#define XORB_MASK (XO_MASK | RB_MASK) - -/* An XS form instruction. */ -#define XS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 2) | (((unsigned long)(rc)) & 1)) -#define XS_MASK XS (0x3f, 0x1ff, 1) - -/* A mask for the FXM version of an XFX form instruction. */ -#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20)) - -/* An XFX form instruction with the FXM field filled in. */ -#define XFXM(op, xop, fxm, p4) \ - (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \ - | ((unsigned long)(p4) << 20)) - -#define SPR_MASK (0x3ff << 11) -/* An XFX form instruction with the SPR field filled in. */ -#define XSPR(op, xop, spr) \ - (X ((op), (xop)) | ((((unsigned long)(spr)) & 0x1f) << 16) | ((((unsigned long)(spr)) & 0x3e0) << 6)) -#define XSPR_MASK (X_MASK | SPR_MASK) - -/* An XFX form instruction with the SPR field filled in except for the - SPRBAT field. */ -#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK) - -/* An XFX form instruction with the SPR field filled in except for the - SPRG field. */ -#define XSPRG_MASK (XSPR_MASK & ~(0x1f << 16)) - -/* An X form instruction with everything filled in except the E field. */ -#define XE_MASK (0xffff7fff) - -/* An X form user context instruction. */ -#define XUC(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) -#define XUC_MASK XUC(0x3f, 0x1f) - -/* The BO encodings used in extended conditional branch mnemonics. */ -#define BODNZF (0x0) -#define BODNZFP (0x1) -#define BODZF (0x2) -#define BODZFP (0x3) -#define BODNZT (0x8) -#define BODNZTP (0x9) -#define BODZT (0xa) -#define BODZTP (0xb) - -#define BOF (0x4) -#define BOFP (0x5) -#define BOFM4 (0x6) -#define BOFP4 (0x7) -#define BOT (0xc) -#define BOTP (0xd) -#define BOTM4 (0xe) -#define BOTP4 (0xf) - -#define BODNZ (0x10) -#define BODNZP (0x11) -#define BODZ (0x12) -#define BODZP (0x13) -#define BODNZM4 (0x18) -#define BODNZP4 (0x19) -#define BODZM4 (0x1a) -#define BODZP4 (0x1b) - -#define BOU (0x14) - -/* The BI condition bit encodings used in extended conditional branch - mnemonics. */ -#define CBLT (0) -#define CBGT (1) -#define CBEQ (2) -#define CBSO (3) - -/* The TO encodings used in extended trap mnemonics. */ -#define TOLGT (0x1) -#define TOLLT (0x2) -#define TOEQ (0x4) -#define TOLGE (0x5) -#define TOLNL (0x5) -#define TOLLE (0x6) -#define TOLNG (0x6) -#define TOGT (0x8) -#define TOGE (0xc) -#define TONL (0xc) -#define TOLT (0x10) -#define TOLE (0x14) -#define TONG (0x14) -#define TONE (0x18) -#define TOU (0x1f) - -/* Smaller names for the flags so each entry in the opcodes table will - fit on a single line. */ -#undef PPC -#define PPC PPC_OPCODE_PPC -#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON -#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC -#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON -#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32 - -/* The opcode table. - - The format of the opcode table is: - - NAME OPCODE MASK FLAGS { OPERANDS } - - NAME is the name of the instruction. - OPCODE is the instruction opcode. - MASK is the opcode mask; this is used to tell the disassembler - which bits in the actual opcode must match OPCODE. - FLAGS are flags indicated what processors support the instruction. - OPERANDS is the list of operands. - - The disassembler reads the table in order and prints the first - instruction which matches, so this table is sorted to put more - specific instructions before more general instructions. It is also - sorted by major opcode. */ - -static const struct powerpc_opcode powerpc_opcodes[] = { - -{ "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI } }, -{ "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI } }, -{ "cmpw", XOPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, -{ "cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, -{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, - -{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } }, -{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SI } }, - -{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA0, SI } }, -{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA0,SI } }, -{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM } }, -{ "bc", B(16,0,0), B_MASK, COM, { BO, BI, BD } }, -{ "bcl", B(16,0,1), B_MASK, COM, { BO, BI, BD } }, -{ "b", B(18,0,0), B_MASK, COM, { LI } }, -{ "bl", B(18,0,1), B_MASK, COM, { LI } }, -{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } }, -{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } }, -{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } }, - -{ "rlwinm", M(21,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } }, -{ "nop", OP(24), 0xffffffff, PPCCOM, { 0 } }, -{ "ori", OP(24), OP_MASK, PPCCOM, { RA, RS, UI } }, -{ "xoris", OP(27), OP_MASK, PPCCOM, { RA, RS, UI } }, -{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA0, RB } }, -{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA0, RB } }, -{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } }, -{ "and", XRC(31,28,0), X_MASK, COM, { RA, RS, RB } }, -{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA } }, -{ "lbzx", X(31,87), X_MASK, COM, { RT, RA0, RB } }, -{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } }, -{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } }, -{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA0, RB } }, -{ "stbx", X(31,215), X_MASK, COM, { RS, RA0, RB } }, -{ "mullw", XO(31,235,0,0), XO_MASK, PPCCOM, { RT, RA, RB } }, -{ "add", XO(31,266,0,0), XO_MASK, PPCCOM, { RT, RA, RB } }, -{ "lhzx", X(31,279), X_MASK, COM, { RT, RA0, RB } }, -{ "xor", XRC(31,316,0), X_MASK, COM, { RA, RS, RB } }, -{ "mflr", XSPR(31,339,8), XSPR_MASK, COM, { RT } }, -{ "sthx", X(31,407), X_MASK, COM, { RS, RA0, RB } }, -{ "mr", XRC(31,444,0), X_MASK, COM, { RA, RS, RBS } }, -{ "or", XRC(31,444,0), X_MASK, COM, { RA, RS, RB } }, -{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB } }, -{ "mtlr", XSPR(31,467,8), XSPR_MASK, COM, { RS } }, -{ "mtctr", XSPR(31,467,9), XSPR_MASK, COM, { RS } }, -{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB } }, -{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA0, RB } }, -{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } }, -{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA0, RB } }, -{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } }, -{ "extsh", XRC(31,922,0), XRB_MASK, PPCCOM, { RA, RS } }, -{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS} }, - -{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA0 } }, -{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA0 } }, -{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA0 } }, -{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } }, -{ "stb", OP(38), OP_MASK, COM, { RS, D, RA0 } }, -{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA0 } }, -{ "sth", OP(44), OP_MASK, COM, { RS, D, RA0 } }, -{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA0 } }, -{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA0 } }, -{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA0 } }, -{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA0 } }, -{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA0 } }, - -{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, -{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, -{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, -{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } }, -{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA0 } }, -{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } }, -{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } }, -{ "fctiwz", XRC(63,15,0), XRA_MASK, PPCCOM, { FRT, FRB } }, -{ "fsub", A(63,20,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } }, -{ "fneg", XRC(63,40,0), XRA_MASK, COM, { FRT, FRB } }, -}; diff --git a/code/qcommon/vm_powerpc_asm.h b/code/qcommon/vm_powerpc_asm.h deleted file mode 100644 index 9bccf18a..00000000 --- a/code/qcommon/vm_powerpc_asm.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2008 Przemyslaw Iskra - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -#ifndef VM_POWERPC_ASM_H -#define VM_POWERPC_ASM_H - -/* - * Register information according to: - * http://refspecs.freestandards.org/elf/elfspec_ppc.pdf - */ - -#define r0 0 // volatile -#define r1 1 // caller safe ( stack pointer ) -#define r2 2 // reserved -#define r3 3 // callee safe -#define r4 4 // callee safe -#define r5 5 // callee safe -#define r6 6 // callee safe -#define r7 7 // callee safe -#define r8 8 // callee safe -#define r9 9 // callee safe -#define r10 10 // callee safe -#define r11 11 // volatile -#define r12 12 // volatile -#define r13 13 // reserved ( small data area ) -#define r14 14 // caller safe -#define r15 15 // caller safe -#define r16 16 // caller safe -#define r17 17 // caller safe -#define r18 18 // caller safe -#define r19 19 // caller safe -#define r20 20 // caller safe -#define r21 21 // caller safe -#define r22 22 // caller safe -#define r23 23 // caller safe -#define r24 24 // caller safe -#define r25 25 // caller safe -#define r26 26 // caller safe -#define r27 27 // caller safe -#define r28 28 // caller safe -#define r29 29 // caller safe -#define r30 30 // caller safe -#define r31 31 // caller safe ( environment pointers ) - -#define f0 0 // callee safe -#define f1 1 // callee safe -#define f2 2 // callee safe -#define f3 3 // callee safe -#define f4 4 // callee safe -#define f5 5 // callee safe -#define f6 6 // callee safe -#define f7 7 // callee safe -#define f8 8 // callee safe -#define f9 9 // callee safe -#define f10 10 // callee safe -#define f11 11 // callee safe -#define f12 12 // callee safe -#define f13 13 // callee safe -#define f14 14 // caller safe -#define f15 15 // caller safe -#define f16 16 // caller safe -#define f17 17 // caller safe -#define f18 18 // caller safe -#define f19 19 // caller safe -#define f20 20 // caller safe -#define f21 21 // caller safe -#define f22 22 // caller safe -#define f23 23 // caller safe -#define f24 24 // caller safe -#define f25 25 // caller safe -#define f26 26 // caller safe -#define f27 27 // caller safe -#define f28 28 // caller safe -#define f29 29 // caller safe -#define f30 30 // caller safe -#define f31 31 // caller safe - -#define cr0 0 // volatile -#define cr1 1 // volatile -#define cr2 2 // caller safe -#define cr3 3 // caller safe -#define cr4 4 // caller safe -#define cr5 5 // volatile -#define cr6 6 // volatile -#define cr7 7 // volatile - -#define lt 0 -#define gt 1 -#define eq 2 -#define so 3 - -// branch bo field values -#define branchLikely 1 -#define branchFalse 4 -#define branchTrue 12 -#define branchAlways 20 - -// branch extensions (change branch type) -#define branchExtLink 0x0001 - - -/* - * This list must match exactly the powerpc_opcodes list from vm_powerpc_asm.c - * If you're changing the original list remember to regenerate this one. You - * may do so using this perl script: - perl -p -e 'BEGIN{%t=("-"=>m=>"+"=>p=>"."=>d=>);$l=""}$o=0 if/^}/; - if($o && s/^{ "(.*?)([\.+-])?".+/i\U$1\E$t{$2}/s){$_.="_" while$l{$_}; - $l{$_}=1;if(length $l.$_ > 70){$s=$_;$_="\t$l\n";$l="$s,"}else - {$l.=" $_,";$_=undef}}else{$o=1 if/powerpc_opcodes.*=/;$_=undef}; - END{print "\t$l\n"}' < vm_powerpc_asm.c - */ - -typedef enum powerpc_iname { - iCMPLWI, iCMPWI, iCMPW, iCMPLW, iFCMPU, iLI, iLIS, iADDI, iADDIS, - iBLTm, iBC, iBCL, iB, iBL, iBLR, iBCTR, iBCTRL, iRLWINM, iNOP, iORI, - iXORIS, iLDX, iLWZX, iSLW, iAND, iSUB, iLBZX, iNEG, iNOT, iSTWX, iSTBX, - iMULLW, iADD, iLHZX, iXOR, iMFLR, iSTHX, iMR, iOR, iDIVWU, iMTLR, - iMTCTR, iDIVW, iLFSX, iSRW, iSTFSX, iSRAW, iEXTSH, iEXTSB, iLWZ, iLBZ, - iSTW, iSTWU, iSTB, iLHZ, iSTH, iLFS, iLFD, iSTFS, iSTFD, iLD, iFDIVS, - iFSUBS, iFADDS, iFMULS, iSTD, iSTDU, iFRSP, iFCTIWZ, iFSUB, iFNEG, -} powerpc_iname_t; - -#include - -typedef uint32_t ppc_instruction_t; - -extern ppc_instruction_t -asm_instruction( powerpc_iname_t, const int, const long int * ); - -#define IN( inst, args... ) \ -({\ - const long int argv[] = { args };\ - const int argc = sizeof( argv ) / sizeof( argv[0] ); \ - asm_instruction( inst, argc, argv );\ -}) - -#endif diff --git a/code/qcommon/vm_sparc.c b/code/qcommon/vm_sparc.c index d79b4324..75cc9d63 100644 --- a/code/qcommon/vm_sparc.c +++ b/code/qcommon/vm_sparc.c @@ -31,7 +31,80 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include "vm_local.h" -#include "vm_sparc.h" + +/* integer regs */ +#define G0 0 +#define G1 1 +#define G2 2 +#define G3 3 +#define G4 4 +#define G5 5 +#define G6 6 +#define G7 7 +#define O0 8 +#define O1 9 +#define O2 10 +#define O3 11 +#define O4 12 +#define O5 13 +#define O6 14 +#define O7 15 +#define L0 16 +#define L1 17 +#define L2 18 +#define L3 19 +#define L4 20 +#define L5 21 +#define L6 22 +#define L7 23 +#define I0 24 +#define I1 25 +#define I2 26 +#define I3 27 +#define I4 28 +#define I5 29 +#define I6 30 +#define I7 31 + +/* float regs */ +#define F0 0 +#define F1 1 +#define F2 2 +#define F3 3 +#define F4 4 +#define F5 5 +#define F6 6 +#define F7 7 +#define F8 8 +#define F9 9 +#define F10 10 +#define F11 11 +#define F12 12 +#define F13 13 +#define F14 14 +#define F15 15 +#define F16 16 +#define F17 17 +#define F18 18 +#define F19 19 +#define F20 20 +#define F21 21 +#define F22 22 +#define F23 23 +#define F24 24 +#define F25 25 +#define F26 26 +#define F27 27 +#define F28 28 +#define F29 29 +#define F30 30 +#define F31 31 + +/* state registers */ +#define Y_REG 0 +#define CCR_REG 2 +#define ASI_REG 3 +#define FPRS_REG 6 /* exit() won't be called but use it because it is marked with noreturn */ #define DIE( reason ) \ diff --git a/code/qcommon/vm_sparc.h b/code/qcommon/vm_sparc.h deleted file mode 100644 index dbed6278..00000000 --- a/code/qcommon/vm_sparc.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef VM_SPARC_H -#define VM_SPARC_H - -/* integer regs */ -#define G0 0 -#define G1 1 -#define G2 2 -#define G3 3 -#define G4 4 -#define G5 5 -#define G6 6 -#define G7 7 -#define O0 8 -#define O1 9 -#define O2 10 -#define O3 11 -#define O4 12 -#define O5 13 -#define O6 14 -#define O7 15 -#define L0 16 -#define L1 17 -#define L2 18 -#define L3 19 -#define L4 20 -#define L5 21 -#define L6 22 -#define L7 23 -#define I0 24 -#define I1 25 -#define I2 26 -#define I3 27 -#define I4 28 -#define I5 29 -#define I6 30 -#define I7 31 - -/* float regs */ -#define F0 0 -#define F1 1 -#define F2 2 -#define F3 3 -#define F4 4 -#define F5 5 -#define F6 6 -#define F7 7 -#define F8 8 -#define F9 9 -#define F10 10 -#define F11 11 -#define F12 12 -#define F13 13 -#define F14 14 -#define F15 15 -#define F16 16 -#define F17 17 -#define F18 18 -#define F19 19 -#define F20 20 -#define F21 21 -#define F22 22 -#define F23 23 -#define F24 24 -#define F25 25 -#define F26 26 -#define F27 27 -#define F28 28 -#define F29 29 -#define F30 30 -#define F31 31 - -/* state registers */ -#define Y_REG 0 -#define CCR_REG 2 -#define ASI_REG 3 -#define FPRS_REG 6 - -#endif