help: about how to use tblgen to constraint operand.

hi, Dear Evan Cheng:

My cpu is i32 embeded CPU. I define pseudo register pair registers.

In mytargetRegisterInfo.td:
def T0: RegisterWithSubRegs<“t0”,[R0,R1]>;

def GPR64 : RegisterClass<“mytarget”, [i64], 64, [T0, T1…]

In mytargetISelLowering.cpp:
I define i1, i8 , i16 and i32 are legal.

  1. I still have problem. I save my function return double value in R0 and R1.
    It is expanded into two i32. But my GPR64 is defined to save i64. llvm finds
    I have i64 GPR register. It will automatically decide not to expand i64 to two i32.

  2. I guess I need a special pseudo instruction to move between GPR32 and GPR64.
    How to move R0, R1 to T1( R2, R3 pair). and don’t convert two i32 to i64?
    Could I use MyTargetInstrInfo::copyRegToReg() to handle this logic issue?

  3. Maybe I can study INSERT_SUBREG/EXTRACT_SUBREG at X86 porting file.

I will do some research more deeply. I think the best way is that TableGen has register pair TypeProfile feature. :frowning:

But I find i64 data will not be ex
09年2月20日,周五, Evan Cheng echeng@apple.com 写道:


hi, Dear Evan Cheng:

My cpu is i32 embeded CPU. I define pseudo register pair registers.

In mytargetRegisterInfo.td:
def T0: RegisterWithSubRegs<“t0”,[R0,R1]>;

def GPR64 : RegisterClass<“mytarget”, [i64], 64, [T0, T1…]

In mytargetISelLowering.cpp:
I define i1, i8 , i16 and i32 are legal.

1. I still have problem. I save my function return double value in R0 and R1.
It is expanded into two i32. But my GPR64 is defined to save i64. llvm finds
I have i64 GPR register. It will automatically decide not to expand i64 to two i32.

2. I guess I need a special pseudo instruction to move between GPR32 and GPR64.
How to move R0, R1 to T1( R2, R3 pair). and don’t convert two i32 to i64?
Could I use MyTargetInstrInfo::copyRegToReg() to handle this logic issue?

No. copyRegToReg only supports copying registers of the same (or compatible register classes).




3. Maybe I can study INSERT_SUBREG/EXTRACT_SUBREG at X86 porting file.

Yes.




I will do some research more deeply. I think the best way is that TableGen has register pair TypeProfile feature. :frowning:

It’s not a tablegen issue. It’s easy to add the constraint to tablegen but the register allocator has to be able to allocate register pairs. That is definitely not a trivial task.

Evan

I try to define a register class
def GPR64 : RegisterClass<“mytarget”, [i64], 64, [T0, T1…]
to simulate even/odd pair of GPR32 register.
Actually, I just use GPR64 as a temporary register.
My CPU just support i32 Integer type directly.
I use FDR to save f64.
def FDR : RegisterClass<“mytarget”, [f64], 64,[FD0, FD1, …]

When I move f64 to even/odd pair register, I first move f64 into GPR64,
then move to 2 GPR32 register.

It worked very well for register binding.

But When I test some case. I find a register class error.

This is probably instruction selection issue. I would look at the dag at various stafes of isel. Try -view-legalize-type-dags, -view-legalize-dags, etc.

Evan