Home | History | Annotate | Download | only in arch
      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 // IsS390xRLD reports whether the op (as defined by an s390x.A* constant) is
     52 // one of the RLD-like instructions that require special handling.
     53 // The FMADD-like instructions behave similarly.
     54 func IsS390xRLD(op obj.As) bool {
     55 	switch op {
     56 	case s390x.AFMADD,
     57 		s390x.AFMADDS,
     58 		s390x.AFMSUB,
     59 		s390x.AFMSUBS,
     60 		s390x.AFNMADD,
     61 		s390x.AFNMADDS,
     62 		s390x.AFNMSUB,
     63 		s390x.AFNMSUBS:
     64 		return true
     65 	}
     66 	return false
     67 }
     68 
     69 // IsS390xCMP reports whether the op (as defined by an s390x.A* constant) is
     70 // one of the CMP instructions that require special handling.
     71 func IsS390xCMP(op obj.As) bool {
     72 	switch op {
     73 	case s390x.ACMP, s390x.ACMPU, s390x.ACMPW, s390x.ACMPWU:
     74 		return true
     75 	}
     76 	return false
     77 }
     78 
     79 // IsS390xNEG reports whether the op (as defined by an s390x.A* constant) is
     80 // one of the NEG-like instructions that require special handling.
     81 func IsS390xNEG(op obj.As) bool {
     82 	switch op {
     83 	case s390x.ANEG, s390x.ANEGW:
     84 		return true
     85 	}
     86 	return false
     87 }
     88 
     89 // IsS390xWithLength reports whether the op (as defined by an s390x.A* constant)
     90 // refers to an instruction which takes a length as its first argument.
     91 func IsS390xWithLength(op obj.As) bool {
     92 	switch op {
     93 	case s390x.AMVC, s390x.ACLC, s390x.AXC, s390x.AOC, s390x.ANC:
     94 		return true
     95 	case s390x.AVLL, s390x.AVSTL:
     96 		return true
     97 	}
     98 	return false
     99 }
    100 
    101 // IsS390xWithIndex reports whether the op (as defined by an s390x.A* constant)
    102 // refers to an instruction which takes an index as its first argument.
    103 func IsS390xWithIndex(op obj.As) bool {
    104 	switch op {
    105 	case s390x.AVSCEG, s390x.AVSCEF, s390x.AVGEG, s390x.AVGEF:
    106 		return true
    107 	case s390x.AVGMG, s390x.AVGMF, s390x.AVGMH, s390x.AVGMB:
    108 		return true
    109 	case s390x.AVLEIG, s390x.AVLEIF, s390x.AVLEIH, s390x.AVLEIB:
    110 		return true
    111 	case s390x.AVLEG, s390x.AVLEF, s390x.AVLEH, s390x.AVLEB:
    112 		return true
    113 	case s390x.AVSTEG, s390x.AVSTEF, s390x.AVSTEH, s390x.AVSTEB:
    114 		return true
    115 	case s390x.AVPDI:
    116 		return true
    117 	}
    118 	return false
    119 }
    120 
    121 func s390xRegisterNumber(name string, n int16) (int16, bool) {
    122 	switch name {
    123 	case "AR":
    124 		if 0 <= n && n <= 15 {
    125 			return s390x.REG_AR0 + n, true
    126 		}
    127 	case "F":
    128 		if 0 <= n && n <= 15 {
    129 			return s390x.REG_F0 + n, true
    130 		}
    131 	case "R":
    132 		if 0 <= n && n <= 15 {
    133 			return s390x.REG_R0 + n, true
    134 		}
    135 	case "V":
    136 		if 0 <= n && n <= 31 {
    137 			return s390x.REG_V0 + n, true
    138 		}
    139 	}
    140 	return 0, false
    141 }
    142