I'm working on the mips16. Mips16 is a mode of the Mips32 (or Mips64) processor. For the most part, it is a compressed form of the MIPS32 instruction set, though not all instructions are supported. Most of the same opcodes and formats are present though sometimes with some restriction. (The micro mips architecture is a true 16 bit compressed form of MIps32 though also with some limitations regarding immediate sizes and such). Mips16 has a mapping of it's registers to those of the MIPS32. Through all of it's instructions, it has direct access to registers 2,3,4,5,6,7, 16,17 though the encoding for 16,17 are 0,1. It's possible to access all other registers only through a move instruction. I'm looking for guidance from those that have done more ports (especially ARM) as to how to organize the register sets and such. It seems like it would be simplest to just create a separate register set for MIPS16 but that would be a hack because those registers are in fact MIPS32 registers, even if they may be encoded differently at times. For optimization, it's possible to change modes and do some computation and then change back, so there are some advantages to not treating the mips16 as if it were a different processor. For example, mips16 has no floating point so in a region of code with floating point you could switch to mips32 and then come back to mips16. Otherwise you will be making a procedure call for each floating point operation. I'm not intending to do such optimizations in this first port but clearly it will be less of a hack in the future if the register sets reflect reality. If you are reading assembly code, it's often hard to tell you are looking at Mips16. They look the same as mips32. I'm trying to avoid duplicating any more of the mips32 than in is necessary. In principal mips16 is just an alternate encoding of Mips32. Thoughts? Tia. Reed
On Jan 24, 2012, at 1:46 AM, Reed Kotler wrote:> Mips16 is a mode of the Mips32 (or Mips64) processor. For the most part, > it is a compressed form of the MIPS32 instruction set, though not all > instructions are supported. Most of the same opcodes and formats are > present though sometimes with some restriction. (The micro mips > architecture is a true 16 bit compressed form of MIps32 though also with > some limitations regarding immediate sizes and such). > > Mips16 has a mapping of it's registers to those of the MIPS32. > > Through all of it's instructions, it has direct access to registers > 2,3,4,5,6,7, 16,17 though the encoding for 16,17 are 0,1. > > It's possible to access all other registers only through a move instruction. > > I'm looking for guidance from those that have done more ports > (especially ARM) as to how to organize the register sets and such. > > It seems like it would be simplest to just create a separate register > set for MIPS16 but that would > be a hack because those registers are in fact MIPS32 registers, even if > they may be encoded > differently at times.Your problem sounds a lot like ARM's Thumb2 instruction set. I would recommend that you keep the existing 32-bit registers, but add a restricted register class for the Mips16 instructions, like ARM's tGPR class. Register classes can overlap, and TableGen will figure out the exact subclass/superclass relationships. You only have to supply the sets. Define the Mips16 instructions as independent instructions, and use the restricted register class to constrain their inputs and outputs. Set the restricted register class as the legal regclass for i32, but make sure you implement the TRI::getLargestLegalSuperClass() target hook. It should return the full CPURegs register class as a legal super-class. The register allocator will then use those registers for live ranges that are only used by copy instructions. Such live ranges are created by live range splitting, so the remaining registers are effectively used as fast spill slots.> I'm trying to avoid duplicating any more of the mips32 than in is > necessary. In principal mips16 is just an alternate encoding of Mips32.I am not familiar with the particular instruction set, but my guess would be that you are better off duplicating the instruction definitions right away. Otherwise, you are looking at lots of special-case code down the road. /jakob
>> I'm trying to avoid duplicating any more of the mips32 than in is >> necessary. In principal mips16 is just an alternate encoding of Mips32. > > I am not familiar with the particular instruction set, but my guess would be that you are better off duplicating the instruction definitions right away. Otherwise, you are looking at lots of special-case code down the road.+1 here. If you don't duplicate them, chances are the code will get pretty hairy. -- Bruno Cardoso Lopes http://www.brunocardoso.cc
Thanks. In case anyone was wondering... register 0 on mips always returns 0 so it's a waste if you are compressing the register field for 16 bit ditto for register 1 which is only used by the assembler when it has to expand a mips instruction macro reassigning them saves 2 registers. On 01/24/2012 07:11 PM, Jakob Stoklund Olesen wrote:> On Jan 24, 2012, at 1:46 AM, Reed Kotler wrote: > >> Mips16 is a mode of the Mips32 (or Mips64) processor. For the most part, >> it is a compressed form of the MIPS32 instruction set, though not all >> instructions are supported. Most of the same opcodes and formats are >> present though sometimes with some restriction. (The micro mips >> architecture is a true 16 bit compressed form of MIps32 though also with >> some limitations regarding immediate sizes and such). >> >> Mips16 has a mapping of it's registers to those of the MIPS32. >> >> Through all of it's instructions, it has direct access to registers >> 2,3,4,5,6,7, 16,17 though the encoding for 16,17 are 0,1. >> >> It's possible to access all other registers only through a move instruction. >> >> I'm looking for guidance from those that have done more ports >> (especially ARM) as to how to organize the register sets and such. >> >> It seems like it would be simplest to just create a separate register >> set for MIPS16 but that would >> be a hack because those registers are in fact MIPS32 registers, even if >> they may be encoded >> differently at times. > Your problem sounds a lot like ARM's Thumb2 instruction set. > > I would recommend that you keep the existing 32-bit registers, but add a restricted register class for the Mips16 instructions, like ARM's tGPR class. Register classes can overlap, and TableGen will figure out the exact subclass/superclass relationships. You only have to supply the sets. > > Define the Mips16 instructions as independent instructions, and use the restricted register class to constrain their inputs and outputs. > > Set the restricted register class as the legal regclass for i32, but make sure you implement the TRI::getLargestLegalSuperClass() target hook. It should return the full CPURegs register class as a legal super-class. The register allocator will then use those registers for live ranges that are only used by copy instructions. Such live ranges are created by live range splitting, so the remaining registers are effectively used as fast spill slots. > >> I'm trying to avoid duplicating any more of the mips32 than in is >> necessary. In principal mips16 is just an alternate encoding of Mips32. > I am not familiar with the particular instruction set, but my guess would be that you are better off duplicating the instruction definitions right away. Otherwise, you are looking at lots of special-case code down the road. > > /jakob >