Is it legal to do something like a !strconcat on a non-string entity? That is, is there some operation that will let me do this (replace SOME_CONCAT with an appropriate operator): (WARNING! Hacked-up tablegen ahead!) multiclass sse_fp_binop_bitwise_rm<bits<8> opc, string OpcodeStr, SDNode OpNode> { // Vector operation emulating scalar (fp) def FsPSrr : PSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32: $src2), !strconcat(OpcodeStr, "ps"\t{$src2, $dst|$dst, $src2}"), [(set FR32:$dst, (!SOME_CONCAT("x86f", OpNode) FR32: $src1, FR32:$src2))]>; // Vector operation def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128: $src2), !strconcat(OpcodeStr, "ps"\t{$src2, $dst|$dst, $src2}"), [(set VR128:$dst, v2i64 (OpNode VR128:$src1, VR128: $src2))]>; // Bitconverted vector operation def PSrm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"), [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)), (memopv2i64 addr:$src2)))]>; // ... } defm AND : ... defm OR : ... I suspect we could get rid of a lot of redundancy if SOME_CONCAT could really work. I've run into a few places where I think something like this could be used. -Dave
On Mar 23, 2009, at 5:56 PM, David Greene wrote:> Is it legal to do something like a !strconcat on a non-string > entity? That > is, is there some operation that will let me do this (replace > SOME_CONCAT with > an appropriate operator):I don't get it, can you try a simpler example on me? :) -Chris> > > (WARNING! Hacked-up tablegen ahead!) > > multiclass sse_fp_binop_bitwise_rm<bits<8> opc, string OpcodeStr, > SDNode OpNode> { > // Vector operation emulating scalar (fp) > def FsPSrr : PSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, > FR32: > $src2), > !strconcat(OpcodeStr, "ps"\t{$src2, $dst|$dst, > $src2}"), > [(set FR32:$dst, (!SOME_CONCAT("x86f", OpNode) > FR32: > $src1, FR32:$src2))]>; > > // Vector operation > def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, > VR128: > $src2), > !strconcat(OpcodeStr, "ps"\t{$src2, $dst|$dst, > $src2}"), > [(set VR128:$dst, v2i64 (OpNode VR128:$src1, > VR128: > $src2))]>; > > // Bitconverted vector operation > def PSrm : PSI<opc, MRMSrcMem, > (outs VR128:$dst), (ins VR128:$src1, f128mem: > $src2), > !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, > $src2}"), > [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 > VR128:$src1)), > (memopv2i64 addr:$src2)))]>; > // ... > } > > defm AND : ... > defm OR : ... > > I suspect we could get rid of a lot of redundancy if SOME_CONCAT > could really > work. I've run into a few places where I think something like this > could be > used. > > -Dave > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On Tuesday 24 March 2009 10:43, Chris Lattner wrote:> On Mar 23, 2009, at 5:56 PM, David Greene wrote: > > Is it legal to do something like a !strconcat on a non-string > > entity? That > > is, is there some operation that will let me do this (replace > > SOME_CONCAT with > > an appropriate operator): > > I don't get it, can you try a simpler example on me? :)Ok, let see if I can construct something.>From the IntrinsicsX86.td file:def int_x86_sse_add_ss : GCCBuiltin<"__builtin_ia32_addss">, Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem, Commutative]>; def int_x86_sse2_add_sd : GCCBuiltin<"__builtin_ia32_addsd">, Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem, Commutative]>; Untested multiclass! Look for SOME_CONCAT. multiclass myintrinsics<bits<8> opc, string OpcodeStr, Intrinsic Intr> { // Scalar intrinsics def SSrr_Int SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32: $src2), !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"), [(set FR32:$dst, (SOME_CONCAT(Intr, _ss) FR32:$src1, FR32: $src2))]> { def SDrr_Int SSI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64: $src2), !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"), [(set FR32:$dst, (SOME_CONCAT(Intr, _sd) FR32:$src1, FR32: $src2))]> { } defm ADD : myintrinsics<0x58, "add", int_x86_sse2_add>; I want the single ADD defm to generate patterns for both the "ss" and "sd" intrinsic variants. I need a way to append "_ss" or "_sd" to the intrinsic name in the pattern. I don't believe there's any way to do this right now but I'm looking into it. I'm currently stepping through TableGen to figure out when pattern fragments (which get instantiated as CodeInits if I understand correctly) have their arguments substituted. At that point I want to scan the pattern and look for special concat operations and munge the resulting strings / names / whatever to do the right thing. Any hints on where to look? -Dave