How to add double to my backend

I want to add double in my backend.How to modify td file to support f64.


1.my backend only support 32 bit load or store.
2.two general registers is used to double.I have def register class.
def D0 : Rd< 0, “D0”, [Gr0, Gr1]>, DwarfRegNum<[65]>;

def FGR64 : RegisterClass<“DSP”, [f64], 64, (add D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12)>;


concrete problems:

  1. how to modify FrameIndex:i32 to FrameIndex:f64(I don’t know to store or load 64 bits)
  2. Is there anything else to consider,like def pat about f64 immediate.

this is part log about my problem.
=== main
Enabling fast-isel
Creating constant: t1: i32 = Constant<0>
Creating new node: t3: i32 = undef
Creating new node: t4: ch = store<(store 4 into %ir.retval)> t0, Constant:i32<0>, FrameIndex:i32<0>, undef:i32
Creating fp constant: t5: f64 = ConstantFP<1.200000e+00>
Creating new node: t7: ch = store<(store 8 into %ir.a)> t4, ConstantFP:f64<1.200000e+00>, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:8:9
Creating fp constant: t8: f64 = ConstantFP<2.700000e+00>
Creating new node: t10: ch = store<(store 8 into %ir.b)> t7, ConstantFP:f64<2.700000e+00>, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:9:9
Creating new node: t11: f64,ch = load<(dereferenceable load 8 from %ir.a)> t10, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:10:13
Creating new node: t12: f64,ch = load<(dereferenceable load 8 from %ir.b)> t10, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:10:17
Creating new node: t13: f64 = fadd t11, t12, …\testcase_8slots\input.c:10:15
Creating new node: t15: ch = TokenFactor t11:1, t12:1, …\testcase_8slots\input.c:10:9
Creating new node: t16: ch = store<(store 8 into %ir.c)> t15, t13, FrameIndex:i32<3>, undef:i32, …\testcase_8slots\input.c:10:9
Creating new node: t18: ch,glue = CopyToReg t16, Register:i32 $v0, Constant:i32<0>, …\testcase_8slots\input.c:11:2
Creating new node: t19: ch = DSPISD::RET t18, Register:i32 $v0, t18:1, …\testcase_8slots\input.c:11:2
Initial selection DAG: %bb.0 ‘main:entry’
SelectionDAG has 20 nodes:
t0: ch = EntryToken
t4: ch = store<(store 4 into %ir.retval)> t0, Constant:i32<0>, FrameIndex:i32<0>, undef:i32
t7: ch = store<(store 8 into %ir.a)> t4, ConstantFP:f64<1.200000e+00>, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:8:9
t10: ch = store<(store 8 into %ir.b)> t7, ConstantFP:f64<2.700000e+00>, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:9:9
t11: f64,ch = load<(dereferenceable load 8 from %ir.a)> t10, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:10:13
t12: f64,ch = load<(dereferenceable load 8 from %ir.b)> t10, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:10:17
t15: ch = TokenFactor t11:1, t12:1, …\testcase_8slots\input.c:10:9
t13: f64 = fadd t11, t12, …\testcase_8slots\input.c:10:15
t16: ch = store<(store 8 into %ir.c)> t15, t13, FrameIndex:i32<3>, undef:i32, …\testcase_8slots\input.c:10:9
t18: ch,glue = CopyToReg t16, Register:i32 $v0, Constant:i32<0>, …\testcase_8slots\input.c:11:2
t19: ch = DSPISD::RET t18, Register:i32 $v0, t18:1, …\testcase_8slots\input.c:11:2

Combining: t0: ch = EntryToken
Optimized lowered selection DAG: %bb.0 ‘main:entry’
SelectionDAG has 29 nodes:
t0: ch = EntryToken
t4: ch = store<(store 4 into %ir.retval)> t0, Constant:i32<0>, FrameIndex:i32<0>, undef:i32
t11: f64,ch = load<(dereferenceable load 8 from %ir.a)> t26, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:10:13
t12: f64,ch = load<(dereferenceable load 8 from %ir.b)> t26, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:10:17
t15: ch = TokenFactor t11:1, t12:1, …\testcase_8slots\input.c:10:9
t13: f64 = fadd t11, t12, …\testcase_8slots\input.c:10:15
t16: ch = store<(store 8 into %ir.c)> t15, t13, FrameIndex:i32<3>, undef:i32, …\testcase_8slots\input.c:10:9
t18: ch,glue = CopyToReg t16, Register:i32 $v0, Constant:i32<0>, …\testcase_8slots\input.c:11:2
t22: ch = store<(store 4 into %ir.b, align 8)> t33, Constant:i32<-1717986918>, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:9:9
t27: i32 = or FrameIndex:i32<2>, Constant:i32<4>, …\testcase_8slots\input.c:9:9
t25: ch = store<(store 4 into %ir.b + 4)> t33, Constant:i32<1074108825>, t27, undef:i32, …\testcase_8slots\input.c:9:9
t26: ch = TokenFactor t22, t25, …\testcase_8slots\input.c:9:9
t30: ch = store<(store 4 into %ir.a, align 8)> t4, Constant:i32<858993459>, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:8:9
t34: i32 = or FrameIndex:i32<1>, Constant:i32<4>, …\testcase_8slots\input.c:8:9
t32: ch = store<(store 4 into %ir.a + 4)> t4, Constant:i32<1072902963>, t34, undef:i32, …\testcase_8slots\input.c:8:9
t33: ch = TokenFactor t30, t32, …\testcase_8slots\input.c:8:9
t19: ch = DSPISD::RET t18, Register:i32 $v0, t18:1, …\testcase_8slots\input.c:11:2

Legalizing node: t29: i32 = Constant<1072902963>
Analyzing result type: i32
Legal result type
Legally typed node: t29: i32 = Constant<1072902963>

Legalizing node: t28: i32 = Constant<858993459>
Analyzing result type: i32
Legal result type
Legally typed node: t28: i32 = Constant<858993459>

Type-legalized selection DAG: %bb.0 ‘main:entry’
SelectionDAG has 29 nodes:
t0: ch = EntryToken
t4: ch = store<(store 4 into %ir.retval)> t0, Constant:i32<0>, FrameIndex:i32<0>, undef:i32
t11: f64,ch = load<(dereferenceable load 8 from %ir.a)> t26, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:10:13
t12: f64,ch = load<(dereferenceable load 8 from %ir.b)> t26, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:10:17
t15: ch = TokenFactor t11:1, t12:1, …\testcase_8slots\input.c:10:9
t13: f64 = fadd t11, t12, …\testcase_8slots\input.c:10:15
t16: ch = store<(store 8 into %ir.c)> t15, t13, FrameIndex:i32<3>, undef:i32, …\testcase_8slots\input.c:10:9
t18: ch,glue = CopyToReg t16, Register:i32 $v0, Constant:i32<0>, …\testcase_8slots\input.c:11:2
t22: ch = store<(store 4 into %ir.b, align 8)> t33, Constant:i32<-1717986918>, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:9:9
t27: i32 = or FrameIndex:i32<2>, Constant:i32<4>, …\testcase_8slots\input.c:9:9
t25: ch = store<(store 4 into %ir.b + 4)> t33, Constant:i32<1074108825>, t27, undef:i32, …\testcase_8slots\input.c:9:9
t26: ch = TokenFactor t22, t25, …\testcase_8slots\input.c:9:9
t30: ch = store<(store 4 into %ir.a, align 8)> t4, Constant:i32<858993459>, FrameIndex:i32<1>, undef:i32, …\testcase_8slots\input.c:8:9
t34: i32 = or FrameIndex:i32<1>, Constant:i32<4>, …\testcase_8slots\input.c:8:9
t32: ch = store<(store 4 into %ir.a + 4)> t4, Constant:i32<1072902963>, t34, undef:i32, …\testcase_8slots\input.c:8:9
t33: ch = TokenFactor t30, t32, …\testcase_8slots\input.c:8:9
t19: ch = DSPISD::RET t18, Register:i32 $v0, t18:1, …\testcase_8slots\input.c:11:2

LLVM ERROR: Cannot select: t12: f64,ch = load<(dereferenceable load 8 from %ir.b)> t26, FrameIndex:i32<2>, undef:i32, …\testcase_8slots\input.c:10:17
t9: i32 = FrameIndex<2>
t3: i32 = undef
In function: main
Stack dump:
0. Program arguments: D:\git_soft\build10\Debug\bin\llc.exe -march=dsp -mcpu=dsp8s1280bdvic -relocation-model=static -pre-RA-sched=vliw-td -disable-dsp-hwloops=1 -debug -filetype=obj D:\tmp_O1\input.ll -o input.out

  1.  Running pass 'Function Pass Manager' on module 'D:\tmp_O1\input.ll'.
    
  2.  Running pass 'DSP DAG->DAG Pattern Instruction Selection' on function '@main'

FrameIndex:i32 refers to your stack pointer type, not the memory type. You don’t want to change that.

You will want some kind of pattern for fconstant to materialize immediates.

For load handling, I think you want to set your LOAD f64 to promote to i64, and then Expand for the i64 loads. It’s possible that won’t work as you expect and you will need custom load lowering to split it.

Thanks.
I have made modifications referring to Sparc’s LowerF128Store/LowerF128load for custom load lowering to split it.

Another problem happen to me.

you are right,I’m in trouble “pattern for fconstant to materialize immediates”