Hi! I'm writing a new back-end for a new architecture. First, I'll do some "tests" with an existing back-end (I chose the Sparc back-end). My architecture has special address-registers and I want to add such new address-registers to my Sparc back-end. 1) I defined a new register call AddrRegs 2) I registered the class AddrRegs (addRegisterClass(MVT::iPTR, .. )) 3) I added method addPointerRegClass() to my InstrInfo class The compiler generates the some code as before, but that seems to be ok, because I haven't used ptr_rc yet. 4) I changed the address mode MEMri: def MEMri : Operand<iPTR> { let PrintMethod = "printMemOperand"; // was: let MIOperandInfo = (ops IntRegs, i32imm); let MIOperandInfo = (ops ptr_rc, i32imm); } for the C code int c; void f(void) { c = 4711; } I get the error message: Register class of operand and regclass of use don't agree! Operand = 0 Op->Val = 0x42b08d60: i32 = SETHIi 0x42b08d00 MI = STri %reg1026 VReg = 1026 VReg RegClass size = 4, align = 4 Expected RegClass size = 4, align = 4 The GlobalAddress for variable c is replaced by an ADD(HI(c), LO (c)) during lowering. I assume the code-generator cant place values in the address registers? All address-registers are elements in the register sets IntRegs and AddrRegs. Using address registers is part of the ppc code-generator and I'm checking that one, but I can't see the differences. Can someone guide me? Thanks, Boris
On Oct 19, 2007, at 8:15 AM, Boris Boesler wrote:> Hi! > > I'm writing a new back-end for a new architecture. First, I'll do > some "tests" with an existing back-end (I chose the Sparc back-end). > My architecture has special address-registers and I want to add such > new address-registers to my Sparc back-end. > > 1) I defined a new register call AddrRegs > 2) I registered the class AddrRegs (addRegisterClass(MVT::iPTR, .. )) > 3) I added method addPointerRegClass() to my InstrInfo class > > The compiler generates the some code as before, but that seems to > be ok, because I haven't used ptr_rc yet. > > 4) I changed the address mode MEMri: > > def MEMri : Operand<iPTR> { > let PrintMethod = "printMemOperand"; > // was: let MIOperandInfo = (ops IntRegs, i32imm); > let MIOperandInfo = (ops ptr_rc, i32imm); > } > > for the C code int c; void f(void) { c = 4711; } I get the error > message: > > Register class of operand and regclass of use don't agree! > Operand = 0 > Op->Val = 0x42b08d60: i32 = SETHIi 0x42b08d00 > MI = STri %reg1026 > VReg = 1026 > VReg RegClass size = 4, align = 4 > Expected RegClass size = 4, align = 4 > > The GlobalAddress for variable c is replaced by an ADD(HI(c), LO > (c)) during lowering. I assume the code-generator cant place values > in the address registers? All address-registers are elements in the > register sets IntRegs and AddrRegs./// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot. multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode> { def rr : F3_1<2, Op3Val, (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), !strconcat(OpcStr, " $b, $c, $dst"), [(set IntRegs:$dst, (OpNode IntRegs:$b, IntRegs: $c))]>; def ri : F3_2<2, Op3Val, (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), !strconcat(OpcStr, " $b, $c, $dst"), [(set IntRegs:$dst, (OpNode IntRegs:$b, simm13:$c))]>; } defm ADD : F3_12<"add", 0b000000, add>; Instruction ADD output register class is IntRegs. It does not match AddrRegs. That's why you are getting the assertion. What you need is to define a parallel set of instructions that target the address register class. Then you can tell the instruction selector to select to these instructions instead of the normal ADD instruction. Perhaps the solution is to custom lower load / store addresses to be "casted". Then write patterns that fold the cast and select to the address register class variant of ADD, etc. There hasn't been any publicly committed targets that require address register class so I haven't spent anytime thinking of a clean solution. For a hackish solution, please read the thread called "Q about instruction pattern matching" between Andreas Fredriksson and myself. Evan> > Using address registers is part of the ppc code-generator and I'm > checking that one, but I can't see the differences. Can someone guide > me? > > Thanks, > Boris > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Hi!>> I'm writing a new back-end for a new architecture. First, I'll do >> some "tests" with an existing back-end (I chose the Sparc back-end). >> My architecture has special address-registers and I want to add such >> new address-registers to my Sparc back-end. >> .... >> The GlobalAddress for variable c is replaced by an ADD(HI(c), LO >> (c)) during lowering. I assume the code-generator cant place values >> in the address registers? All address-registers are elements in the >> register sets IntRegs and AddrRegs. > > /// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot. > multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode> { > .... > } > > defm ADD : F3_12<"add", 0b000000, add>; > > Instruction ADD output register class is IntRegs. It does not match > AddrRegs. That's why you are getting the assertion.The address register set AddrRegs is a subset of IntRegs. Do you compare the register set identifiers instead of the register itself and if it is within a set?> What you need is to define a parallel set of instructions that target > the address register class.Every operand or or target of the 3 address-machine can be a data or address register. Then I had to write 8 (2^3) patterns per instruction. But register classes/sets are used to fold that. I do that since ~1996 (~11 years)! We used BEG as code-generator-generator.> There > hasn't been any publicly committed targets that require address > register class so I haven't spent anytime thinking of a clean > solution.This has nothing to do with address registers! This has to do with registers and their sets. Address registers are an obvious / famous example, but one can think of other cases. Free your mind! ;-) A register can be in multiple sets! If a value is written into a register r of class A, then a pattern with class B can match if register r is an element of class B. In Bottom Up Pattern Matchers we use "chain rules" to transform a non-terminal/register-class to another non-terminal/register-class. So, what should I do next? What do you suggest? Modify the register allocator? Thanks, Boris