mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: use numeric condition code masks on s390x
Prior to this CL conditional branches on s390x always used an extended mnemonic such as BNE, BLT and so on to represent branch instructions with different condition code masks. This CL adds support for numeric condition code masks to the s390x SSA backend so that we can encode the condition under which a Block's successor is chosen as a field in that Block rather than in its type. This change will be useful as we come to add support for combined compare-and-branch instructions. Rather than trying to add extended mnemonics for every possible combination of mask and compare-and- branch instruction we can instead use a single mnemonic for each instruction. Change-Id: Idb7458f187b50906877d683695c291dff5279553 Reviewed-on: https://go-review.googlesource.com/c/go/+/197178 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
8506b7d42f
commit
cf03238020
13 changed files with 897 additions and 1657 deletions
120
src/cmd/internal/obj/s390x/condition_code.go
Normal file
120
src/cmd/internal/obj/s390x/condition_code.go
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package s390x
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// CCMask represents a 4-bit condition code mask. Bits that
|
||||
// are not part of the mask should be 0.
|
||||
//
|
||||
// Condition code masks represent the 4 possible values of
|
||||
// the 2-bit condition code as individual bits. Since IBM Z
|
||||
// is a big-endian platform bits are numbered from left to
|
||||
// right. The lowest value, 0, is represented by 8 (0b1000)
|
||||
// and the highest value, 3, is represented by 1 (0b0001).
|
||||
//
|
||||
// Note that condition code values have different semantics
|
||||
// depending on the instruction that set the condition code.
|
||||
// The names given here assume that the condition code was
|
||||
// set by an integer or floating point comparison. Other
|
||||
// instructions may use these same codes to indicate
|
||||
// different results such as a carry or overflow.
|
||||
type CCMask uint8
|
||||
|
||||
const (
|
||||
Never CCMask = 0 // no-op
|
||||
|
||||
// 1-bit masks
|
||||
Equal CCMask = 1 << 3
|
||||
Less CCMask = 1 << 2
|
||||
Greater CCMask = 1 << 1
|
||||
Unordered CCMask = 1 << 0
|
||||
|
||||
// 2-bit masks
|
||||
EqualOrUnordered CCMask = Equal | Unordered // not less and not greater
|
||||
LessOrEqual CCMask = Less | Equal // ordered and not greater
|
||||
LessOrGreater CCMask = Less | Greater // ordered and not equal
|
||||
LessOrUnordered CCMask = Less | Unordered // not greater and not equal
|
||||
GreaterOrEqual CCMask = Greater | Equal // ordered and not less
|
||||
GreaterOrUnordered CCMask = Greater | Unordered // not less and not equal
|
||||
|
||||
// 3-bit masks
|
||||
NotEqual CCMask = Always ^ Equal
|
||||
NotLess CCMask = Always ^ Less
|
||||
NotGreater CCMask = Always ^ Greater
|
||||
NotUnordered CCMask = Always ^ Unordered
|
||||
|
||||
// 4-bit mask
|
||||
Always CCMask = Equal | Less | Greater | Unordered
|
||||
)
|
||||
|
||||
// Inverse returns the complement of the condition code mask.
|
||||
func (c CCMask) Inverse() CCMask {
|
||||
return c ^ Always
|
||||
}
|
||||
|
||||
// ReverseComparison swaps the bits at 0b0100 and 0b0010 in the mask,
|
||||
// reversing the behavior of greater than and less than conditions.
|
||||
func (c CCMask) ReverseComparison() CCMask {
|
||||
r := c & EqualOrUnordered
|
||||
if c&Less != 0 {
|
||||
r |= Greater
|
||||
}
|
||||
if c&Greater != 0 {
|
||||
r |= Less
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (c CCMask) String() string {
|
||||
switch c {
|
||||
// 0-bit mask
|
||||
case Never:
|
||||
return "Never"
|
||||
|
||||
// 1-bit masks
|
||||
case Equal:
|
||||
return "Equal"
|
||||
case Less:
|
||||
return "Less"
|
||||
case Greater:
|
||||
return "Greater"
|
||||
case Unordered:
|
||||
return "Unordered"
|
||||
|
||||
// 2-bit masks
|
||||
case EqualOrUnordered:
|
||||
return "EqualOrUnordered"
|
||||
case LessOrEqual:
|
||||
return "LessOrEqual"
|
||||
case LessOrGreater:
|
||||
return "LessOrGreater"
|
||||
case LessOrUnordered:
|
||||
return "LessOrUnordered"
|
||||
case GreaterOrEqual:
|
||||
return "GreaterOrEqual"
|
||||
case GreaterOrUnordered:
|
||||
return "GreaterOrUnordered"
|
||||
|
||||
// 3-bit masks
|
||||
case NotEqual:
|
||||
return "NotEqual"
|
||||
case NotLess:
|
||||
return "NotLess"
|
||||
case NotGreater:
|
||||
return "NotGreater"
|
||||
case NotUnordered:
|
||||
return "NotUnordered"
|
||||
|
||||
// 4-bit mask
|
||||
case Always:
|
||||
return "Always"
|
||||
}
|
||||
|
||||
// invalid
|
||||
return fmt.Sprintf("Invalid (%#x)", c)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue