LLVM学习日志13——add intrinsics mapping the new instruction

如题,增加新的指令应该是我最终的目标。有两个方式来实现这个目标,一个是增加通用的DAG,这样所有的ISA都会增加上这条指令,但是比较难,因为DAG有合法化、简化什么的,比较难。所以我选择第二条,就是为某一个特定的ISA增加一个内联函数(intrinsics ),通过这个内联函数来链接到新的指令。

首先,和增加伪指令一样,在clang中增加一条intrinsic function。具体就不写了。有区别的是在Target中,下面描述Target/X86中的修改。

首先,也是在X86ISelLowering.h中增加max_qb,增加一个X86的ISD。

在X86ISelLowering.cpp中增加case,增加这个ISD的对应case X86ISD::max_qb:             return "X86ISD::max_qb";

前面都是一样的

在X86IntrinsicsInfo.h中增加自己的intrinsic。因为不需要工具链,所以添加位置需要找好,而且这个比较坑的是要按照字母的顺序进行排序,那时我找了好久错误都找不到,最后还是在论坛求助的。

 X86_INTRINSIC_DATA(max_qb, INTR_TYPE_2OP, X86ISD::max_qb, 0),

在X86InstrInfo.td中增加一个SDNode,因为我准备输出和整数乘法格式一样的二进制编码,这样,在读取二级制文件时也简单方便一点。所以SDNode中的参数参照了IMUL。具体定义可以在inlclude/Target中找到。

def X86max_qb : SDNode<"X86ISD::max_qb", SDTBinaryArithWithFlags,[SDNPCommutative]>;

然后在X86InstrArithmetic.td中定义具体输出形式,在这儿定义和在X86InstrInfo.td没区别,只是LLVM对不同指令进行了一个分类。


let Defs = [EFLAGS] in {
let Constraints = "$src1 = $dst" in {
let isCommutable = 1 in {
def max_qb : I<0xF0,MRMSrcReg, (outs  GR32:$dst), (ins GR32:$src1,GR32:$src2),
	         "max_qb{w}\t {$dst, $src1,$src2|$dst, $src2,$src1}", [(set GR32:$dst,EFLAGS,(X86max_qb GR32:$src1, GR32:$src2))]>,  Sched<[WriteIMul32Reg]>,
	          OpSize32 ;

}
}
}

讲解一下,进行了一些限制,比如src1=dst,这是因为X86的基础指令只能有两个寄存器(操作数),所以让一个寄存器等于输出,EFLAGS也是满足EFLAGS。def定义了这条指令,其中F0是操作码,MRMSrcReg是指令类型,后面的定义输出和输入,GR32是32位寄存器的意思。“”号内的是表示汇编的输出形式,在编译后的汇编显示格式。set这句就是二进制的形式。Sched定义了指令在机器中的一些时序,延时、周期数等,最后的OpSize32表示这个是32的操作数,如果遇到64时会自动补全。

对了,得把原来的F0的指令注释掉,不然就会报错说指令覆盖。

下面开始简单测试:

#include <stdlib.h>
#include <stdio.h>

int main()
{
  int a;
  int b;
  int c;
  a=2;b=6;
  c=__builtin_x86_max_qb (a,b); 
  printf("%d \n",c);


}

使用命令

clang -emit-llvm -O0 test.c -c -o test.bc

llc test.bc

得到test.s。(节选了一部分),可以看到在汇编中得到了max_qb,所以添加指令成功。但是比较尴尬,我想运行一直失败,3周后我才想起可能是因为运行其实和编译器是无关的,编译器只是负责编译成二进制文件,而运行时看cpu中固有的指令读取方式的,所以下一步,我想修改一下gem5,让指令运行起来

     movl	$2, -12(%rbp)
	movl	$6, -8(%rbp)
	movl	-12(%rbp), %eax
	movl	-8(%rbp), %ecx
	max_qbw	 %eax, %eax,%ecx
	movl	%eax, -4(%rbp)
	movl	-4(%rbp), %esi
	movabsq	$.L.str, %rdi
	movb	$0, %al
	callq	printf

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值