llvm libLLVMCore源码分析 07 - Unary & Binary Operators

源码路径

llvm\include\llvm\IR\Instruction.h

llvm\include\llvm\IR\Instruction.def

llvm\include\llvm\IR\Instructions.h

llvm\include\llvm\IR\InstrTypes.h

Unary Operators

所有的Unary Operators在llvm中均使用类UnaryOperator实现,没有单独的子类。

fneg

fneg指令用于返回操作数的负值。

语法

<result> = fneg [fast-math flags]* <ty> <op1>   ; yields ty:result

参数说明:

ty:必须是浮点类型或者浮点类型矢量(Vector)。

语义

该指令复制操作数的值,并将标志位翻转。该指令可以使用fast-math flags,使能不安全的浮点数优化。

示例

<result> = fneg float %val          ; yields float:result = -%var

Binary Operators

所有的Binary Operators在llvm中均使用类BinaryOperator实现,没有单独的子类。

add

add指令返回两个操作数的和。

语法

<result> = add <ty> <op1>, <op2>          ; yields ty:result
<result> = add nuw <ty> <op1>, <op2>      ; yields ty:result
<result> = add nsw <ty> <op1>, <op2>      ; yields ty:result
<result> = add nuw nsw <ty> <op1>, <op2>  ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

add指令返回两个操作数的和。如果result为无符号数且溢出,则result = result % 2n,其中n为result的位宽。因为LLVM整形使用二进制补码的形式,所以add指令可以同时用于有符号和无符号数。

nuw表示“No Unsigned Wrap”,如果设置了该关键字,则无符号数加法溢出得到的result为Poison Value。

nsw表示"No signed Wrap",如果设置了该关键字,则有符号数加法溢出得到的result为Poison Value。

示例

<result> = add i32 4, %var          ; yields i32:result = 4 + %var

fadd

fadd指令返回两个操作数的和。

语法

<result> = fadd [fast-math flags]* <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是浮点类型或者浮点类型矢量。

语义

fadd指令返回两个操作数的和。该指令可以使用fast-math flags,使能不安全的浮点数优化。

示例

<result> = fadd float 4.0, %var          ; yields float:result = 4.0 + %var

sub

sub指令返回两个操作数的差。

语法

<result> = sub <ty> <op1>, <op2>          ; yields ty:result
<result> = sub nuw <ty> <op1>, <op2>      ; yields ty:result
<result> = sub nsw <ty> <op1>, <op2>      ; yields ty:result
<result> = sub nuw nsw <ty> <op1>, <op2>  ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

sub指令返回两个操作数的差。如果result为无符号数且溢出,则result = result % 2n,其中n为result的位宽。因为LLVM整形使用二进制补码的形式,所以sub指令可以同时用于有符号和无符号数。

nuw表示“No Unsigned Wrap”,如果设置了该关键字,则无符号数减法溢出得到的result为Poison Value。

nsw表示"No signed Wrap",如果设置了该关键字,则有符号数减法溢出得到的result为Poison Value。

示例

<result> = sub i32 4, %var          ; yields i32:result = 4 - %var
<result> = sub i32 0, %val          ; yields i32:result = -%var

fsub

fsub指令返回两个操作数的差。

语法

<result> = fsub [fast-math flags]* <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是浮点类型或者浮点类型矢量。

语义

fsub指令返回两个操作数的差。该指令可以使用fast-math flags,使能不安全的浮点数优化。

示例

<result> = fsub float 4.0, %var           ; yields float:result = 4.0 - %var
<result> = fsub float -0.0, %val          ; yields float:result = -%var

mul

mul指令返回两个操作数的乘积。

语法

<result> = mul <ty> <op1>, <op2>          ; yields ty:result
<result> = mul nuw <ty> <op1>, <op2>      ; yields ty:result
<result> = mul nsw <ty> <op1>, <op2>      ; yields ty:result
<result> = mul nuw nsw <ty> <op1>, <op2>  ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

mul指令返回两个操作数的乘积。如果result为无符号数且溢出,则result = result % 2n,其中n为result的位宽。因为LLVM整形使用二进制补码的形式,所以mul指令可以同时用于有符号和无符号数。

nuw表示“No Unsigned Wrap”,如果设置了该关键字,则无符号数乘法溢出得到的result为Poison Value。

nsw表示"No signed Wrap",如果设置了该关键字,则有符号数乘法溢出得到的result为Poison Value。

示例

<result> = mul i32 4, %var          ; yields i32:result = 4 * %var

fmul

fmul指令返回两个操作数的乘积。

语法

<result> = fmul [fast-math flags]* <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是浮点类型或者浮点类型矢量。

语义

fmul指令返回两个操作数的乘积。该指令可以使用fast-math flags,使能不安全的浮点数优化。

示例

<result> = fmul float 4.0, %var          ; yields float:result = 4.0 * %var

udiv

udiv指令返回两个操作数的商。

语法

<result> = udiv <ty> <op1>, <op2>         ; yields ty:result
<result> = udiv exact <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty: 两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

udiv指令返回两个无符号数的商,除0的行为是未定义的。如果使用了exact关键字,则如果op1不是op2的整数倍,result是一个Poison Value。

示例

<result> = udiv i32 4, %var          ; yields i32:result = 4 / %var

sdiv

sdiv指令返回两个操作数的商。

语法

<result> = sdiv <ty> <op1>, <op2>         ; yields ty:result
<result> = sdiv exact <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty: 两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

udiv指令返回两个有符号数的商,除0的行为是未定义的。除法溢出同样会导致未定义行为,比如做32位除法:-2147483648 / -1(2147483648超过了有符号整型的范围)

如果使用了exact关键字,则如果op1不是op2的整数倍,result是一个Poison Value。

示例

<result> = sdiv i32 4, %var          ; yields i32:result = 4 / %var

fdiv

fdiv指令返回两个操作数的商。

语法

<result> = fdiv [fast-math flags]* <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty: 两个操作数的类型相同,必须是浮点类型或者浮点类型矢量。

语义

fdiv指令返回两个浮点数的商。该指令可以使用fast-math flags,使能不安全的浮点数优化。

示例

<result> = fdiv float 4.0, %var          ; yields float:result = 4.0 / %var

 urem

urem指令返回两个操作数的余数。

语法

<result> = urem <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty: 两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

urem指令返回两个无符号数的余数,除0的行为是未定义的。

示例

<result> = urem i32 4, %var          ; yields i32:result = 4 % %var

srem

 srem指令返回两个操作数的余数。

语法

<result> = srem <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty: 两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

srem指令返回两个无符号数的余数,余数的符号和被除数一致。除0的行为是未定义的。除法溢出同样会导致未定义行为,比如做32位除法:-2147483648 / -1(2147483648超过了有符号整型的范围)

示例

<result> = frem float 4.0, %var          ; yields float:result = 4.0 % %var

shl

shl指令返回第1个操作数左移第2个操作数指定的bit的结果。

语法

<result> = shl <ty> <op1>, <op2>           ; yields ty:result
<result> = shl nuw <ty> <op1>, <op2>       ; yields ty:result
<result> = shl nsw <ty> <op1>, <op2>       ; yields ty:result
<result> = shl nuw nsw <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。其中op2会被当作无符号数处理。

语义

result = op1 * 2^op2 mod 2^n

其中n是result的位宽,如果op2等于或者大于op1的位宽,则result为一个Poison Value。

nuw表示“No Unsigned Wrap”,如果设置了该关键字,则无符号数移位溢出得到的result为Poison Value。

nsw表示"No signed Wrap",如果设置了该关键字,则有符号数移位溢出得到的result为Poison Value。

示例

<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>

lshr

lshr指令返回第1个操作数逻辑右移第2个操作数指定的bit并用0填充MSB的结果。

语法

<result> = lshr <ty> <op1>, <op2>         ; yields ty:result
<result> = lshr exact <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。其中op2会被当作无符号数处理。

语义

指令实现逻辑右移,既使用0填充移位后的MSB。如果op2等于或大于op1的位宽,则result为Poison Value。如果设置了exact关键字,则如果右移出的bit不为0,result为Poison Value。

示例

<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 = 0x7F
<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>

ashr

ashr指令返回第1个操作数算术右移第2个操作数指定的bit的结果。

语法

<result> = ashr <ty> <op1>, <op2>         ; yields ty:result
<result> = ashr exact <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。其中op2会被当作无符号数处理。

语义

指令实现算术右移,既使用op1的符号位填充移位后的MSB。如果op2等于或大于op1的位宽,则result为Poison Value。如果设置了exact关键字,则如果右移出的bit不为0,result为Poison Value。

示例

<result> = ashr i32 4, 1   ; yields i32:result = 2
<result> = ashr i32 4, 2   ; yields i32:result = 1
<result> = ashr i8  4, 3   ; yields i8:result = 0
<result> = ashr i8 -2, 1   ; yields i8:result = -1
<result> = ashr i32 1, 32  ; undefined
<result> = ashr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 3>   ; yields: result=<2 x i32> < i32 -1, i32 0>

and

and指令返回两个操作数的按位逻辑与的结果。

语法

<result> = and <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

and指令的真值表:

In0In1Out
000
010
100
111

示例

<result> = and i32 4, %var         ; yields i32:result = 4 & %var
<result> = and i32 15, 40          ; yields i32:result = 8
<result> = and i32 4, 8            ; yields i32:result = 0

or

and指令返回两个操作数的按位逻辑或的结果。

语法

<result> = or <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

or指令的真值表:

In0In1Out
000
011
101
111

示例

<result> = or i32 4, %var         ; yields i32:result = 4 | %var
<result> = or i32 15, 40          ; yields i32:result = 47
<result> = or i32 4, 8            ; yields i32:result = 12

xor

and指令返回两个操作数的按位逻辑异或的结果。

语法

<result> = xor <ty> <op1>, <op2>   ; yields ty:result

参数说明:

ty:两个操作数的类型相同,必须是整型或者整形类型矢量。

语义

xor指令的真值表:

In0In1Out
000
011
101
110

示例

<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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值