提交 e9df3881 编写于 作者: B Ben Shi

llvm: implement translation of bitwise logic and shift operations.

上级 74a1e417
# Test the llvm backend.
# Test bitwise logic.
var a i64 = 0x55555555
var b i64 = 0x33333333
var c i16 = 0x5555
var d i16 = 0x3333
var e u8 = 0x55
var f u8 = 0x33
fn main() {
println("not ", 0x55555555, " = ", bw_not(0x55555555))
println("not ", 0xaaaaaaaa, " = ", bw_not(0xaaaaaaaa))
println(a, " and ", b, " = ", bw_and(a, b), "(", 0x11111111, ")")
println(c, " or ", d, " = ", bw_or(c, d), "(", 0x7777, ")")
println(e, " xor ", f, " = ", bw_xor(e, f), "(", 0x66, ")")
}
fn bw_not(a u32) u32 {
return ^a
}
fn bw_and(a i64, b i64) i64 {
return a & b
}
fn bw_or(a i16, b i16) i16 {
return a | b
}
fn bw_xor(a u8, b u8) u8 {
return a ^ b
}
# Test the llvm backend.
# Test logical/arithmetic shift operations.
var ga i32 = -15
var gb i32 = 15
var gc i64 = -15
var gd i64 = 15
var ge u16 = 0xffcc
fn main() {
println(ga, " << ", 2, " = ", test_shl_0(ga, 2))
println(gb, " << ", 2, " = ", test_shl_1(gb, 2))
println(ga, " << ", 2, " = ", test_shl_2(ga, 2))
println(gc, " >> ", 2, " = ", test_ashr_0(gc, 2))
println(gd, " >> ", 2, " = ", test_ashr_1(gd, 2))
println(ge, " >> ", 2, " = ", test_lshr_0(ge, 2), "(", 0x3ff3, ")")
println(ge, " >> ", 2, " = ", test_lshr_1(ge, 2), "(", 0x3ff3, ")")
}
fn test_shl_0(a i32, b i64) i32 {
return a << b
}
fn test_shl_1(a i32, b i16) i32 {
return a << b
}
fn test_shl_2(a i32, b u16) i32 {
return a << b
}
fn test_ashr_0(a i64, b i64) i64 {
return a >> b
}
fn test_ashr_1(a i64, b u32) i64 {
return a >> b
}
fn test_lshr_0(a u16, b i32) u16 {
return a >> b
}
fn test_lshr_1(a u16, b u8) u16 {
return a >> b
}
......@@ -218,9 +218,15 @@ func (p *Compiler) compileUnOp(val *ssa.UnOp) error {
p.output.WriteString(" ")
p.output.WriteString(getValueStr(val.X))
case token.XOR:
p.output.WriteString("xor ")
p.output.WriteString(getTypeStr(val.X.Type(), p.target))
p.output.WriteString(" ")
p.output.WriteString(getValueStr(val.X))
p.output.WriteString(", -1")
default:
p.output.WriteString(" ; " + val.Name() + " = " + val.String())
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
}
p.output.WriteString("\n")
......@@ -240,6 +246,11 @@ func (p *Compiler) compileBinOp(val *ssa.BinOp) error {
token.GTR: "icmp sgt",
token.LEQ: "icmp sle",
token.GEQ: "icmp sge",
token.AND: "and",
token.OR: "or",
token.XOR: "xor",
token.SHL: "shl",
token.SHR: "ashr",
}
uintOpMap := map[token.Token]string{
token.ADD: "add",
......@@ -253,6 +264,11 @@ func (p *Compiler) compileBinOp(val *ssa.BinOp) error {
token.GTR: "icmp ugt",
token.LEQ: "icmp ule",
token.GEQ: "icmp uge",
token.AND: "and",
token.OR: "or",
token.XOR: "xor",
token.SHL: "shl",
token.SHR: "lshr",
}
floatOpMap := map[token.Token]string{
token.ADD: "fadd",
......@@ -278,8 +294,39 @@ func (p *Compiler) compileBinOp(val *ssa.BinOp) error {
opMap = uintOpMap
}
// Special process for float32 constants.
// Special process for shift operations.
xStr, yStr := "", ""
if val.Op == token.SHL || val.Op == token.SHR {
tyCOp := ""
switch {
case getTypeSize(val.X.Type(), p.target) < getTypeSize(val.Y.Type(), p.target):
tyCOp = "trunc"
case getTypeSize(val.X.Type(), p.target) > getTypeSize(val.Y.Type(), p.target):
_, yIsSigned := checkType(val.Y.Type())
if !isSigned || !yIsSigned {
tyCOp = "zext"
} else {
tyCOp = "sext"
}
default:
}
if tyCOp != "" {
yStr = fmt.Sprintf("%%tmp%d", rand.Int())
p.output.WriteString(" ")
p.output.WriteString(yStr)
p.output.WriteString(" = ")
p.output.WriteString(tyCOp)
p.output.WriteString(" ")
p.output.WriteString(getTypeStr(val.Y.Type(), p.target))
p.output.WriteString(" ")
p.output.WriteString(getValueStr(val.Y))
p.output.WriteString(" to ")
p.output.WriteString(getTypeStr(val.X.Type(), p.target))
p.output.WriteString("\n")
}
}
// Special process for float32 constants.
if isConstFloat32(val.X) {
xStr = p.wrapConstFloat32(val.X)
} else {
......@@ -287,7 +334,7 @@ func (p *Compiler) compileBinOp(val *ssa.BinOp) error {
}
if isConstFloat32(val.Y) {
yStr = p.wrapConstFloat32(val.Y)
} else {
} else if yStr == "" {
yStr = getValueStr(val.Y)
}
......@@ -307,9 +354,7 @@ func (p *Compiler) compileBinOp(val *ssa.BinOp) error {
return nil
}
p.output.WriteString(" ; " + val.Name() + " = " + val.String() + "\n")
return nil
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
}
func (p *Compiler) compileCall(val *ssa.Call) error {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册