On 01/19/2016 04:59 AM, Woon yung Liu wrote:
In my current attempt at adding support for the TI mode, the MMI
definitions are added into a MD file for the R5900 and some functions
(i.e. mips_output_move) were modified to allow certain moves for the
TI mode of the R5900 target. However, while it seems like TI-mode
integers can now be passed between functions and used with the MMI
(within one 128-bit GPR), GCC still treats 128-bit moves as complex
moves (split across two 64-bit registers); its built-in functions
expect both $a0 and $a1 to be used if the first argument is a 128-bit
value. To return a 128-bit value, both $v0 and $v1 are used.
You'll have to adjust FUNCTION_ARG and its counterpart for return values
to describe how to pass these 128 bit values around.
Otherwise, I believe that there are two solutions to the problem with
the calling convention (but again, I have no idea which is better):
1. Keep the target as 64-bit. Support for MMI will be either
compromised (i.e. made to assemble and split the 128-bit vectors upon
entry/exit) or totally omitted. Perhaps omission would be best so
that there will never be a compromise in performance.
2. Promote the word size of the R5900 to 128-bit. I think that SONY
might have done this, as the code from their late games used lq/sq
(quard-word load/store) to preserve registers. However, I think that
this goes against the existing ABIs, doesn't it? Plus the MMI
instruction set is proprietary and isn't used in any other MIPS.
Changing the word size to 128 bit should not be necessary.
Many ports define patterns for operations on data types that are larger
than their native word mode.
You really need to add the new patterns for operating on 128bit values
to the machine description and adjust the parameter passing routines .
We did have to force the compiler to assume a 64bit *host* datatype
(long long). I don't recall the reasoning behind that.
If I carry on with my current design, I suppose that I need to make
it so that the hi1/lo1 registers are never used for other MIPS
targets. I didn't find a RTL constraint that meant something like
"nothing", so I made the new constraints define MD1_REGS (hi1/lo1) as
their MD_REGS (hi/lo) equivalents if the target is not the R5900
(much like the DSP ACC register constraint, ka). But unlike the DSP
ACC register constraint (ka), my constraints are used as alternatives
alongside whatever (i.e. x for hi/lo or ka for hi/lo/acc) that was
originally there. Would this be acceptable, given that there will be
two similar alternatives for some instructions when the target is not
the R5900?
You define the registers & constraints normally. However, you make the
registers conditional on the target in use. ie, if you're not on an
r5900 target, then mark those registers as fixed. That will prevent the
compiler from trying to use them on things other than the r5900.
Again, you may want to find the old cygnus releases of the r5900
toolchain. It had functional access to the second hi/lo register pair.
jeff