github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/compile/internal/ssa/shift_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssa 6 7 import ( 8 "testing" 9 ) 10 11 func TestShiftConstAMD64(t *testing.T) { 12 c := testConfig(t) 13 fun := makeConstShiftFunc(c, 18, OpLsh64x64, TypeUInt64) 14 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHLQconst: 1, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 15 16 fun = makeConstShiftFunc(c, 66, OpLsh64x64, TypeUInt64) 17 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHLQconst: 0, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 18 19 fun = makeConstShiftFunc(c, 18, OpRsh64Ux64, TypeUInt64) 20 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHRQconst: 1, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 21 22 fun = makeConstShiftFunc(c, 66, OpRsh64Ux64, TypeUInt64) 23 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHRQconst: 0, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 24 25 fun = makeConstShiftFunc(c, 18, OpRsh64x64, TypeInt64) 26 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SARQconst: 1, OpAMD64CMPQconst: 0}) 27 28 fun = makeConstShiftFunc(c, 66, OpRsh64x64, TypeInt64) 29 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SARQconst: 1, OpAMD64CMPQconst: 0}) 30 } 31 32 func makeConstShiftFunc(c *Conf, amount int64, op Op, typ Type) fun { 33 ptyp := &TypeImpl{Size_: 8, Ptr: true, Name: "ptr"} 34 fun := c.Fun("entry", 35 Bloc("entry", 36 Valu("mem", OpInitMem, TypeMem, 0, nil), 37 Valu("SP", OpSP, TypeUInt64, 0, nil), 38 Valu("argptr", OpOffPtr, ptyp, 8, nil, "SP"), 39 Valu("resptr", OpOffPtr, ptyp, 16, nil, "SP"), 40 Valu("load", OpLoad, typ, 0, nil, "argptr", "mem"), 41 Valu("c", OpConst64, TypeUInt64, amount, nil), 42 Valu("shift", op, typ, 0, nil, "load", "c"), 43 Valu("store", OpStore, TypeMem, 0, TypeUInt64, "resptr", "shift", "mem"), 44 Exit("store"))) 45 Compile(fun.f) 46 return fun 47 } 48 49 func TestShiftToExtensionAMD64(t *testing.T) { 50 // Test that eligible pairs of constant shifts are converted to extensions. 51 // For example: 52 // (uint64(x) << 32) >> 32 -> uint64(uint32(x)) 53 ops := map[Op]int{ 54 OpAMD64SHLQconst: 0, OpAMD64SHLLconst: 0, 55 OpAMD64SHRQconst: 0, OpAMD64SHRLconst: 0, 56 OpAMD64SARQconst: 0, OpAMD64SARLconst: 0, 57 } 58 tests := [...]struct { 59 amount int64 60 left, right Op 61 typ Type 62 }{ 63 // unsigned 64 {56, OpLsh64x64, OpRsh64Ux64, TypeUInt64}, 65 {48, OpLsh64x64, OpRsh64Ux64, TypeUInt64}, 66 {32, OpLsh64x64, OpRsh64Ux64, TypeUInt64}, 67 {24, OpLsh32x64, OpRsh32Ux64, TypeUInt32}, 68 {16, OpLsh32x64, OpRsh32Ux64, TypeUInt32}, 69 {8, OpLsh16x64, OpRsh16Ux64, TypeUInt16}, 70 // signed 71 {56, OpLsh64x64, OpRsh64x64, TypeInt64}, 72 {48, OpLsh64x64, OpRsh64x64, TypeInt64}, 73 {32, OpLsh64x64, OpRsh64x64, TypeInt64}, 74 {24, OpLsh32x64, OpRsh32x64, TypeInt32}, 75 {16, OpLsh32x64, OpRsh32x64, TypeInt32}, 76 {8, OpLsh16x64, OpRsh16x64, TypeInt16}, 77 } 78 c := testConfig(t) 79 for _, tc := range tests { 80 fun := makeShiftExtensionFunc(c, tc.amount, tc.left, tc.right, tc.typ) 81 checkOpcodeCounts(t, fun.f, ops) 82 } 83 } 84 85 // makeShiftExtensionFunc generates a function containing: 86 // 87 // (rshift (lshift (Const64 [amount])) (Const64 [amount])) 88 // 89 // This may be equivalent to a sign or zero extension. 90 func makeShiftExtensionFunc(c *Conf, amount int64, lshift, rshift Op, typ Type) fun { 91 ptyp := &TypeImpl{Size_: 8, Ptr: true, Name: "ptr"} 92 fun := c.Fun("entry", 93 Bloc("entry", 94 Valu("mem", OpInitMem, TypeMem, 0, nil), 95 Valu("SP", OpSP, TypeUInt64, 0, nil), 96 Valu("argptr", OpOffPtr, ptyp, 8, nil, "SP"), 97 Valu("resptr", OpOffPtr, ptyp, 16, nil, "SP"), 98 Valu("load", OpLoad, typ, 0, nil, "argptr", "mem"), 99 Valu("c", OpConst64, TypeUInt64, amount, nil), 100 Valu("lshift", lshift, typ, 0, nil, "load", "c"), 101 Valu("rshift", rshift, typ, 0, nil, "lshift", "c"), 102 Valu("store", OpStore, TypeMem, 0, TypeUInt64, "resptr", "rshift", "mem"), 103 Exit("store"))) 104 Compile(fun.f) 105 return fun 106 }