github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/cmd/asm/internal/arch/s390x.go (about)

     1  // Copyright 2016 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  // This file encapsulates some of the odd characteristics of the
     6  // s390x instruction set, to minimize its interaction
     7  // with the core of the assembler.
     8  
     9  package arch
    10  
    11  import (
    12  	"cmd/internal/obj"
    13  	"cmd/internal/obj/s390x"
    14  )
    15  
    16  func jumpS390x(word string) bool {
    17  	switch word {
    18  	case "BC",
    19  		"BCL",
    20  		"BEQ",
    21  		"BGE",
    22  		"BGT",
    23  		"BL",
    24  		"BLE",
    25  		"BLEU",
    26  		"BLT",
    27  		"BLTU",
    28  		"BNE",
    29  		"BR",
    30  		"BVC",
    31  		"BVS",
    32  		"CMPBEQ",
    33  		"CMPBGE",
    34  		"CMPBGT",
    35  		"CMPBLE",
    36  		"CMPBLT",
    37  		"CMPBNE",
    38  		"CMPUBEQ",
    39  		"CMPUBGE",
    40  		"CMPUBGT",
    41  		"CMPUBLE",
    42  		"CMPUBLT",
    43  		"CMPUBNE",
    44  		"CALL",
    45  		"JMP":
    46  		return true
    47  	}
    48  	return false
    49  }
    50  
    51  // IsS390xCMP reports whether the op (as defined by an s390x.A* constant) is
    52  // one of the CMP instructions that require special handling.
    53  func IsS390xCMP(op obj.As) bool {
    54  	switch op {
    55  	case s390x.ACMP, s390x.ACMPU, s390x.ACMPW, s390x.ACMPWU:
    56  		return true
    57  	}
    58  	return false
    59  }
    60  
    61  // IsS390xNEG reports whether the op (as defined by an s390x.A* constant) is
    62  // one of the NEG-like instructions that require special handling.
    63  func IsS390xNEG(op obj.As) bool {
    64  	switch op {
    65  	case s390x.ANEG, s390x.ANEGW:
    66  		return true
    67  	}
    68  	return false
    69  }
    70  
    71  // IsS390xWithLength reports whether the op (as defined by an s390x.A* constant)
    72  // refers to an instruction which takes a length as its first argument.
    73  func IsS390xWithLength(op obj.As) bool {
    74  	switch op {
    75  	case s390x.AMVC, s390x.ACLC, s390x.AXC, s390x.AOC, s390x.ANC:
    76  		return true
    77  	case s390x.AVLL, s390x.AVSTL:
    78  		return true
    79  	}
    80  	return false
    81  }
    82  
    83  // IsS390xWithIndex reports whether the op (as defined by an s390x.A* constant)
    84  // refers to an instruction which takes an index as its first argument.
    85  func IsS390xWithIndex(op obj.As) bool {
    86  	switch op {
    87  	case s390x.AVSCEG, s390x.AVSCEF, s390x.AVGEG, s390x.AVGEF:
    88  		return true
    89  	case s390x.AVGMG, s390x.AVGMF, s390x.AVGMH, s390x.AVGMB:
    90  		return true
    91  	case s390x.AVLEIG, s390x.AVLEIF, s390x.AVLEIH, s390x.AVLEIB:
    92  		return true
    93  	case s390x.AVLEG, s390x.AVLEF, s390x.AVLEH, s390x.AVLEB:
    94  		return true
    95  	case s390x.AVSTEG, s390x.AVSTEF, s390x.AVSTEH, s390x.AVSTEB:
    96  		return true
    97  	case s390x.AVPDI:
    98  		return true
    99  	}
   100  	return false
   101  }
   102  
   103  func s390xRegisterNumber(name string, n int16) (int16, bool) {
   104  	switch name {
   105  	case "AR":
   106  		if 0 <= n && n <= 15 {
   107  			return s390x.REG_AR0 + n, true
   108  		}
   109  	case "F":
   110  		if 0 <= n && n <= 15 {
   111  			return s390x.REG_F0 + n, true
   112  		}
   113  	case "R":
   114  		if 0 <= n && n <= 15 {
   115  			return s390x.REG_R0 + n, true
   116  		}
   117  	case "V":
   118  		if 0 <= n && n <= 31 {
   119  			return s390x.REG_V0 + n, true
   120  		}
   121  	}
   122  	return 0, false
   123  }