下面是我对llvm汇编中一些不常用的指令的总结:
‘shl’指令
语法:
<result> = shl <ty> <op1>, <op2>
; yields {ty}:result
概述:
shl指令把第一个操作数(op1)向左移动(op2)个指定位,并把该值返回给result。
参数:
shl指令的两个参数都必须是同样的类型,为整型或者是整型的容器(vector),‘op2’被认为是无符号值。
语义:
生成的值是op1 * 2op2 mod 2n,这里n是result的宽度。如果op2是负数,或者op2的值与op1的比特位数相等或者更大,那么这个结果(result)就是不明确的。如果参数是容器(vector)的话,那么每个容器元素op1都要相应的移动op2个位数。
例子:
<result> = shl i32 4, %var ; yields {i32}: 4 << %var
<result> = shl i32 4, 2 ; yields {i32}: 16
<result> = shl i32 1, 10 ; yields {i32}: 1024
<result> = shl i32 1, 32 ; undefined
<result> = shl <2 x i32> < i32 1, i32 1>, < i32 1, i32 2> ; yields: result=<2 x i32> < i32 2, i32 4>
’zext.. to‘指令
语法:
<result> = zext <ty> <value> to <ty2> ; yields ty2
概述:
zext指令把操作数使用0扩展为ty2类型。
参数:
zext指令要转换的数值,必须是整型,目标类型也必须是整型。value的位的大小必须比目标类型ty2的位的大小小。
语义:
zext指令用0填充value的高阶位,直到达到目标类型ty2的大小。
When zero extending from i1, the result will always be either 0 or 1.(具体解释见例子)。
例子:
%X = zext i32 257 to i64 ; yields i64:257
%Y = zext i1 true to i32 ; yields i32:1
’lshr‘指令
语法:
<result> = lshr <ty> <op1>, <op2> ; yields {ty}:result
概述:
lshr指令(逻辑右移)把第一个操作数op1向右移动指定数量(op2)的位数,用0填充左边的高位,最后返回第一个操作数给result。
参数:
lshr指令的两个参数必须都是相同的整型或者整型类容器(vector)。op2被认为是一个无符号值。
语义:
该指令总是执行一个逻辑右移的操作。移位之后,结果result中的最高位将被0填充。如果op2的值与op1的位数相等,或者更大,那么结果result不明确。如果参数是容器的话,那么每个容器元素op1都要相应的移动op2个位数。
例子:
<result> = lshr i32 4, 1 ; yields {i32}:result = 2
<result> = lshr i32 4, 2 ; yields {i32}:result = 1
<result> = lshr i8 4, 3 ; yields {i8}:result = 0
<result> = lshr i8 -2, 1 ; yields {i8}:result = 0x7FFFFFFF
<result> = lshr i32 1, 32 ; undefined
<result> = lshr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 2> ; yields: result=<2 x i32> < i32 0x7FFFFFFF, i32 1>
’’trunc.. to‘指令
语法:
<result> = trunc <ty> <value> to <ty2> ; yields ty2
概述:
trunc指令把它的操作数缩短为ty2类型。
参数:
trunc指令要缩短的数值必须是整型,指定result的尺寸和类型的ty2也必须是整型的。value位的大小必须比ty2的位的大小大。同等大小的类型也是不允许的。
语义:
trunc指令把value的高阶位缩短(即去掉),把剩余的位(bits)转化为ty2。因为源操作数的位大小必须比目标类型的位大小大,所以trunc不能是个空操作转换。它总是会缩短位的。
例子:
%X = trunc i32 257 to i8 ; yields i8:1 说明:257---100 000 001
%Y = trunc i32 123 to i1 ; yields i1:true 说明:123---111 101 1
%Y = trunc i32 122 to i1 ; yields i1:false 说明:122---111 101 0
phi指令中,一个数据对中的第一个值是来自上一个bb中的,要注意。
xor指令:
语法:
<result> = xor <ty> <op1>, <op2> ; yields {ty}:result
概述:
xor指令返回两个操作数异或运算后的值。该指令也可以用来执行对一个操作数的取反操作(当然这需要op2操作数是-1,-1对应的16进制补码是0xFFFF),这有点像C语言中的“~”运算符。
参数:
xor指令的两个参数必须是整型或者整形类容器(vecotr),两个参数的类型必须一致。
语义:
xor指令异或规则如下表所示:
In0 | In1 | OUt |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
例子(前三个例子是异或,最后一个例子实际上是对%v变量取反,这个取反是不论%v正负属性的):
<result> = xor i32 4, %var ; yields {i32}:result = 4 ^ %var <result> = xor i32 15, 40 ; yields {i32}:result = 39 <result> = xor i32 4, 8 ; yields {i32}:result = 12 <result> = xor i32 %V, -1 ; yields {i32}:result = ~%V
select指令:
语法:
<result> = select selty <cond>, <ty> <val1>, <ty> <val2> ; yields ty
selty is either i1 or {<N x i1>}
概述:
select指令被用来在基于某个条件的情况下选取一个值,没有分支情况。
参数:
select指令需要一个i1值或者是i1值的一个容器(vecotr)来说明条件。两个val值必须是同一个类型。如果val1和val2是容器类型,而条件cond是标量类型,那么整个容器(vector)都会被选中,而不是单个元素。
语义:
如果条件是i1并且i1的值是1,这个指令会返回第一个值参数。否则,它会返回第二个值参数。如果条件是i1容器,那么这个值参数必须是同样大小的容器,选择会一个元素一个元素的进行。
例子:
%X = select i1 true, i8 17, i8 42 ; yields i8:17
llvm-2.6版本需要注意代码生成器还不支持条件是容器类型。