github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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  // 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  }