📄 m88k.h
字号:
#define LONG_DOUBLE_TYPE_SIZE 64/* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. Somewhat arbitrary. It matches the bit field patterns. */#define BITS_BIG_ENDIAN 1/* Define this if most significant byte of a word is the lowest numbered. That is true on the m88000. */#define BYTES_BIG_ENDIAN 1/* Define this if most significant word of a multiword number is the lowest numbered. For the m88000 we can decide arbitrarily since there are no machine instructions for them. */#define WORDS_BIG_ENDIAN 1/* Width of a word, in units (bytes). */#define UNITS_PER_WORD 4/* Allocation boundary (in *bits*) for storing arguments in argument list. */#define PARM_BOUNDARY 32/* Largest alignment for stack parameters (if greater than PARM_BOUNDARY). */#define MAX_PARM_BOUNDARY 64/* Boundary (in *bits*) on which stack pointer should be aligned. */#define STACK_BOUNDARY 128/* Allocation boundary (in *bits*) for the code of a function. On the m88100, it is desirable to align to a cache line. However, SVR3 targets only provided 8 byte alignment. The m88110 cache is small, so align to an 8 byte boundary. Pack code tightly when compiling crtstuff.c. */#define FUNCTION_BOUNDARY (flag_inhibit_size_directive ? 32 : \ (TARGET_88100 && TARGET_SVR4 ? 128 : 64))/* No data type wants to be aligned rounder than this. */#define BIGGEST_ALIGNMENT 64/* The best alignment to use in cases where we have a choice. */#define FASTEST_ALIGNMENT (TARGET_88100 ? 32 : 64)/* Make strings 4/8 byte aligned so strcpy from constants will be faster. */#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ ((TREE_CODE (EXP) == STRING_CST \ && (ALIGN) < FASTEST_ALIGNMENT) \ ? FASTEST_ALIGNMENT : (ALIGN))/* Make arrays of chars 4/8 byte aligned for the same reasons. */#define DATA_ALIGNMENT(TYPE, ALIGN) \ (TREE_CODE (TYPE) == ARRAY_TYPE \ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))/* Alignment of field after `int : 0' in a structure. Ignored with PCC_BITFIELD_TYPE_MATTERS. *//* #define EMPTY_FIELD_BOUNDARY 8 *//* Every structure's size must be a multiple of this. */#define STRUCTURE_SIZE_BOUNDARY 8/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */#define STRICT_ALIGNMENT 1/* A bit-field declared as `int' forces `int' alignment for the struct. */#define PCC_BITFIELD_TYPE_MATTERS 1/* Maximum size (in bits) to use for the largest integral type that replaces a BLKmode type. *//* #define MAX_FIXED_MODE_SIZE 0 *//*** Register Usage ***//* Number of actual hardware registers. The hardware registers are assigned numbers for the compiler from 0 to just below FIRST_PSEUDO_REGISTER. All registers that the compiler knows about must be given numbers, even those that are not normally considered general registers. The m88100 has a General Register File (GRF) of 32 32-bit registers. The m88110 adds an Extended Register File (XRF) of 32 80-bit registers. */#define FIRST_PSEUDO_REGISTER 64#define FIRST_EXTENDED_REGISTER 32/* General notes on extended registers, their use and misuse. Possible good uses: spill area instead of memory. -waste if only used once floating point calculations -probably a waste unless we have run out of general purpose registers freeing up general purpose registers -e.g. may be able to have more loop invariants if floating point is moved into extended registers. I've noticed wasteful moves into and out of extended registers; e.g. a load into x21, then inside a loop a move into r24, then r24 used as input to an fadd. Why not just load into r24 to begin with? Maybe the new cse.c will address this. This wastes a move, but the load,store and move could have been saved had extended registers been used throughout. E.g. in the code following code, if z and xz are placed in extended registers, there is no need to save preserve registers. long c=1,d=1,e=1,f=1,g=1,h=1,i=1,j=1,k; double z=0,xz=4.5; foo(a,b) long a,b; { while (a < b) { k = b + c + d + e + f + g + h + a + i + j++; z += xz; a++; } printf("k= %d; z=%f;\n", k, z); } I've found that it is possible to change the constraints (putting * before the 'r' constraints int the fadd.ddd instruction) and get the entire addition and store to go into extended registers. However, this also forces simple addition and return of floating point arguments to a function into extended registers. Not the correct solution. Found the following note in local-alloc.c which may explain why I can't get both registers to be in extended registers since two are allocated in local-alloc and one in global-alloc. Doesn't explain (I don't believe) why an extended register is used instead of just using the preserve register. from local-alloc.c: We have provision to exempt registers, even when they are contained within the block, that can be tied to others that are not contained in it. This is so that global_alloc could process them both and tie them then. But this is currently disabled since tying in global_alloc is not yet implemented. The explanation of why the preserved register is not used is as follows, I believe. The registers are being allocated in order. Tying is not done so efficiently, so when it comes time to do the first allocation, there are no registers left to use without spilling except extended registers. Then when the next pseudo register needs a hard reg, there are still no registers to be had for free, but this one must be a GRF reg instead of an extended reg, so a preserve register is spilled. Thus the move from extended to GRF is necessitated. I do not believe this can be 'fixed' through the files in config/m88k. gcc seems to sometimes make worse use of register allocation -- not counting moves -- whenever extended registers are present. For example in the whetstone, the simple for loop (slightly modified) for(i = 1; i <= n1; i++) { x1 = (x1 + x2 + x3 - x4) * t; x2 = (x1 + x2 - x3 + x4) * t; x3 = (x1 - x2 + x3 + x4) * t; x4 = (x1 + x2 + x3 + x4) * t; } in general loads the high bits of the addresses of x2-x4 and i into registers outside the loop. Whenever extended registers are used, it loads all of these inside the loop. My conjecture is that since the 88110 has so many registers, and gcc makes no distinction at this point -- just that they are not fixed, that in loop.c it believes it can expect a number of registers to be available. Then it allocates 'too many' in local-alloc which causes problems later. 'Too many' are allocated because a large portion of the registers are extended registers and cannot be used for certain purposes ( e.g. hold the address of a variable). When this loop is compiled on its own, the problem does not occur. I don't know the solution yet, though it is probably in the base sources. Possibly a different way to calculate "threshold". *//* 1 for registers that have pervasive standard uses and are not available for the register allocator. Registers r14-r25 and x22-x29 are expected to be preserved across function calls. On the 88000, the standard uses of the General Register File (GRF) are: Reg 0 = Pseudo argument pointer (hardware fixed to 0). Reg 1 = Subroutine return pointer (hardware). Reg 2-9 = Parameter registers (OCS). Reg 10 = OCS reserved temporary. Reg 11 = Static link if needed [OCS reserved temporary]. Reg 12 = Address of structure return (OCS). Reg 13 = OCS reserved temporary. Reg 14-25 = Preserved register set. Reg 26-29 = Reserved by OCS and ABI. Reg 30 = Frame pointer (Common use). Reg 31 = Stack pointer. The following follows the current 88open UCS specification for the Extended Register File (XRF): Reg 32 = x0 Always equal to zero Reg 33-53 = x1-x21 Temporary registers (Caller Save) Reg 54-61 = x22-x29 Preserver registers (Callee Save) Reg 62-63 = x30-x31 Reserved for future ABI use. Note: The current 88110 extended register mapping is subject to change. The bias towards caller-save registers is based on the presumption that memory traffic can potentially be reduced by allowing the "caller" to save only that part of the register which is actually being used. (i.e. don't do a st.x if a st.d is sufficient). Also, in scientific code (a.k.a. Fortran), the large number of variables defined in common blocks may require that almost all registers be saved across calls anyway. */#define FIXED_REGISTERS \ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}/* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any registers that can be used without being saved. The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. */#define CALL_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}/* Macro to conditionally modify fixed_regs/call_used_regs. */#define CONDITIONAL_REGISTER_USAGE \ { \ if (! TARGET_88110) \ { \ register int i; \ for (i = FIRST_EXTENDED_REGISTER; i < FIRST_PSEUDO_REGISTER; i++) \ { \ fixed_regs[i] = 1; \ call_used_regs[i] = 1; \ } \ } \ if (flag_pic) \ { \ /* Current hack to deal with -fpic -O2 problems. */ \ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ global_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ } \ }/* True if register is an extended register. */#define XRF_REGNO_P(N) ((N) < FIRST_PSEUDO_REGISTER && (N) >= FIRST_EXTENDED_REGISTER) /* Return number of consecutive hard regs needed starting at reg REGNO to hold something of mode MODE. This is ordinarily the length in words of a value of mode MODE but can be less for certain modes in special long registers. On the m88000, GRF registers hold 32-bits and XRF registers hold 80-bits. An XRF register can hold any mode, but two GRF registers are required for larger modes. */#define HARD_REGNO_NREGS(REGNO, MODE) \ (XRF_REGNO_P (REGNO) \ ? 1 : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. For double integers, we never put the value into an odd register so that the operators don't run into the situation where the high part of one of the inputs is the low part of the result register. (It's ok if the output registers are the same as the input registers.) The XRF registers can hold all modes, but only DF and SF modes can be manipulated in these registers. The compiler should be allowed to use these as a fast spill area. */#define HARD_REGNO_MODE_OK(REGNO, MODE) \ (XRF_REGNO_P(REGNO) \ ? (TARGET_88110 && GET_MODE_CLASS (MODE) == MODE_FLOAT) \ : (((MODE) != DImode && (MODE) != DFmode && (MODE) != DCmode) \ || ((REGNO) & 1) == 0))/* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, for any hard reg, then this must be 0 for correct output. */#define MODES_TIEABLE_P(MODE1, MODE2) \ (((MODE1) == DFmode || (MODE1) == DCmode || (MODE1) == DImode \ || (TARGET_88110 && GET_MODE_CLASS (MODE1) == MODE_FLOAT)) \ == ((MODE2) == DFmode || (MODE2) == DCmode || (MODE2) == DImode \ || (TARGET_88110 && GET_MODE_CLASS (MODE2) == MODE_FLOAT)))/* Specify the registers used for certain standard purposes. The values of these macros are register numbers. *//* the m88000 pc isn't overloaded on a register that the compiler knows about. *//* #define PC_REGNUM *//* Register to use for pushing function arguments. */#define STACK_POINTER_REGNUM 31/* Base register for access to local variables of the function. */#define FRAME_POINTER_REGNUM 30/* Base register for access to arguments of the function. */#define ARG_POINTER_REGNUM 0/* Register used in cases where a temporary is known to be safe to use. */#define TEMP_REGNUM 10/* Register in which static-chain is passed to a function. */#define STATIC_CHAIN_REGNUM 11/* Register in which address to store a structure value is passed to a function. */#define STRUCT_VALUE_REGNUM 12/* Register to hold the addressing base for position independent code access to data items. */#define PIC_OFFSET_TABLE_REGNUM 25/* Order in which registers are preferred (most to least). Use temp registers, then param registers top down. Preserve registers are
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -