github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/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 "github.com/gagliardetto/golang-go/cmd/compile/internal/types" 9 "testing" 10 ) 11 12 func TestShiftConstAMD64(t *testing.T) { 13 c := testConfig(t) 14 fun := makeConstShiftFunc(c, 18, OpLsh64x64, c.config.Types.UInt64) 15 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHLQconst: 1, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 16 17 fun = makeConstShiftFunc(c, 66, OpLsh64x64, c.config.Types.UInt64) 18 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHLQconst: 0, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 19 20 fun = makeConstShiftFunc(c, 18, OpRsh64Ux64, c.config.Types.UInt64) 21 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHRQconst: 1, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 22 23 fun = makeConstShiftFunc(c, 66, OpRsh64Ux64, c.config.Types.UInt64) 24 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SHRQconst: 0, OpAMD64CMPQconst: 0, OpAMD64ANDQconst: 0}) 25 26 fun = makeConstShiftFunc(c, 18, OpRsh64x64, c.config.Types.Int64) 27 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SARQconst: 1, OpAMD64CMPQconst: 0}) 28 29 fun = makeConstShiftFunc(c, 66, OpRsh64x64, c.config.Types.Int64) 30 checkOpcodeCounts(t, fun.f, map[Op]int{OpAMD64SARQconst: 1, OpAMD64CMPQconst: 0}) 31 } 32 33 func makeConstShiftFunc(c *Conf, amount int64, op Op, typ *types.Type) fun { 34 ptyp := c.config.Types.BytePtr 35 fun := c.Fun("entry", 36 Bloc("entry", 37 Valu("mem", OpInitMem, types.TypeMem, 0, nil), 38 Valu("SP", OpSP, c.config.Types.Uintptr, 0, nil), 39 Valu("argptr", OpOffPtr, ptyp, 8, nil, "SP"), 40 Valu("resptr", OpOffPtr, ptyp, 16, nil, "SP"), 41 Valu("load", OpLoad, typ, 0, nil, "argptr", "mem"), 42 Valu("c", OpConst64, c.config.Types.UInt64, amount, nil), 43 Valu("shift", op, typ, 0, nil, "load", "c"), 44 Valu("store", OpStore, types.TypeMem, 0, c.config.Types.UInt64, "resptr", "shift", "mem"), 45 Exit("store"))) 46 Compile(fun.f) 47 return fun 48 } 49 50 func TestShiftToExtensionAMD64(t *testing.T) { 51 c := testConfig(t) 52 // Test that eligible pairs of constant shifts are converted to extensions. 53 // For example: 54 // (uint64(x) << 32) >> 32 -> uint64(uint32(x)) 55 ops := map[Op]int{ 56 OpAMD64SHLQconst: 0, OpAMD64SHLLconst: 0, 57 OpAMD64SHRQconst: 0, OpAMD64SHRLconst: 0, 58 OpAMD64SARQconst: 0, OpAMD64SARLconst: 0, 59 } 60 tests := [...]struct { 61 amount int64 62 left, right Op 63 typ *types.Type 64 }{ 65 // unsigned 66 {56, OpLsh64x64, OpRsh64Ux64, c.config.Types.UInt64}, 67 {48, OpLsh64x64, OpRsh64Ux64, c.config.Types.UInt64}, 68 {32, OpLsh64x64, OpRsh64Ux64, c.config.Types.UInt64}, 69 {24, OpLsh32x64, OpRsh32Ux64, c.config.Types.UInt32}, 70 {16, OpLsh32x64, OpRsh32Ux64, c.config.Types.UInt32}, 71 {8, OpLsh16x64, OpRsh16Ux64, c.config.Types.UInt16}, 72 // signed 73 {56, OpLsh64x64, OpRsh64x64, c.config.Types.Int64}, 74 {48, OpLsh64x64, OpRsh64x64, c.config.Types.Int64}, 75 {32, OpLsh64x64, OpRsh64x64, c.config.Types.Int64}, 76 {24, OpLsh32x64, OpRsh32x64, c.config.Types.Int32}, 77 {16, OpLsh32x64, OpRsh32x64, c.config.Types.Int32}, 78 {8, OpLsh16x64, OpRsh16x64, c.config.Types.Int16}, 79 } 80 for _, tc := range tests { 81 fun := makeShiftExtensionFunc(c, tc.amount, tc.left, tc.right, tc.typ) 82 checkOpcodeCounts(t, fun.f, ops) 83 } 84 } 85 86 // makeShiftExtensionFunc generates a function containing: 87 // 88 // (rshift (lshift (Const64 [amount])) (Const64 [amount])) 89 // 90 // This may be equivalent to a sign or zero extension. 91 func makeShiftExtensionFunc(c *Conf, amount int64, lshift, rshift Op, typ *types.Type) fun { 92 ptyp := c.config.Types.BytePtr 93 fun := c.Fun("entry", 94 Bloc("entry", 95 Valu("mem", OpInitMem, types.TypeMem, 0, nil), 96 Valu("SP", OpSP, c.config.Types.Uintptr, 0, nil), 97 Valu("argptr", OpOffPtr, ptyp, 8, nil, "SP"), 98 Valu("resptr", OpOffPtr, ptyp, 16, nil, "SP"), 99 Valu("load", OpLoad, typ, 0, nil, "argptr", "mem"), 100 Valu("c", OpConst64, c.config.Types.UInt64, amount, nil), 101 Valu("lshift", lshift, typ, 0, nil, "load", "c"), 102 Valu("rshift", rshift, typ, 0, nil, "lshift", "c"), 103 Valu("store", OpStore, types.TypeMem, 0, c.config.Types.UInt64, "resptr", "rshift", "mem"), 104 Exit("store"))) 105 Compile(fun.f) 106 return fun 107 }