From 51062863a5c34d81e296cf15c61140911037cf3b Mon Sep 17 00:00:00 2001 From: Wim Date: Mon, 6 Aug 2018 21:47:05 +0200 Subject: Use mod vendor for vendored directory (backwards compatible) --- vendor/github.com/google/gops/internal/LICENSE | 27 - .../github.com/google/gops/internal/dwarf/dwarf.go | 600 --- .../google/gops/internal/dwarf/dwarf_defs.go | 483 -- .../github.com/google/gops/internal/goobj/read.go | 714 --- .../google/gops/internal/obj/addrtype_string.go | 27 - .../google/gops/internal/obj/arm/a.out.go | 338 -- .../google/gops/internal/obj/arm/anames.go | 108 - .../google/gops/internal/obj/arm/anames5.go | 73 - .../google/gops/internal/obj/arm/asm5.go | 2846 ------------ .../google/gops/internal/obj/arm/list5.go | 84 - .../google/gops/internal/obj/arm/obj5.go | 1055 ----- .../google/gops/internal/obj/arm64/a.out.go | 719 --- .../google/gops/internal/obj/arm64/anames.go | 370 -- .../google/gops/internal/obj/arm64/anames7.go | 70 - .../google/gops/internal/obj/arm64/asm7.go | 4374 ------------------ .../google/gops/internal/obj/arm64/list7.go | 115 - .../google/gops/internal/obj/arm64/obj7.go | 1005 ----- vendor/github.com/google/gops/internal/obj/data.go | 190 - vendor/github.com/google/gops/internal/obj/flag.go | 115 - .../google/gops/internal/obj/funcdata.go | 48 - vendor/github.com/google/gops/internal/obj/go.go | 86 - vendor/github.com/google/gops/internal/obj/ld.go | 92 - vendor/github.com/google/gops/internal/obj/link.go | 974 ---- .../google/gops/internal/obj/mips/a.out.go | 375 -- .../google/gops/internal/obj/mips/anames.go | 113 - .../google/gops/internal/obj/mips/anames0.go | 44 - .../google/gops/internal/obj/mips/asm0.go | 1783 -------- .../google/gops/internal/obj/mips/list0.go | 85 - .../google/gops/internal/obj/mips/obj0.go | 1497 ------ vendor/github.com/google/gops/internal/obj/obj.go | 306 -- .../github.com/google/gops/internal/obj/objfile.go | 606 --- vendor/github.com/google/gops/internal/obj/pass.go | 217 - vendor/github.com/google/gops/internal/obj/pcln.go | 281 -- .../github.com/google/gops/internal/obj/plist.go | 208 - .../google/gops/internal/obj/ppc64/a.out.go | 941 ---- .../google/gops/internal/obj/ppc64/anames.go | 549 --- .../google/gops/internal/obj/ppc64/anames9.go | 49 - .../google/gops/internal/obj/ppc64/asm9.go | 4552 ------------------- .../google/gops/internal/obj/ppc64/list9.go | 105 - .../google/gops/internal/obj/ppc64/obj9.go | 1251 ----- .../google/gops/internal/obj/reloctype_string.go | 17 - .../google/gops/internal/obj/s390x/a.out.go | 926 ---- .../google/gops/internal/obj/s390x/anames.go | 675 --- .../google/gops/internal/obj/s390x/anamesz.go | 39 - .../google/gops/internal/obj/s390x/asmz.go | 4766 -------------------- .../google/gops/internal/obj/s390x/listz.go | 74 - .../google/gops/internal/obj/s390x/objz.go | 1029 ----- .../google/gops/internal/obj/s390x/vector.go | 1061 ----- .../github.com/google/gops/internal/obj/stack.go | 21 - .../google/gops/internal/obj/stringer.go | 104 - vendor/github.com/google/gops/internal/obj/sym.go | 88 - .../google/gops/internal/obj/symkind_string.go | 16 - .../google/gops/internal/obj/textflag.go | 50 - .../google/gops/internal/obj/typekind.go | 41 - vendor/github.com/google/gops/internal/obj/util.go | 499 -- .../google/gops/internal/obj/x86/a.out.go | 1009 ----- .../google/gops/internal/obj/x86/anames.go | 769 ---- .../google/gops/internal/obj/x86/asm6.go | 4536 ------------------- .../google/gops/internal/obj/x86/list6.go | 181 - .../google/gops/internal/obj/x86/obj6.go | 1481 ------ .../google/gops/internal/obj/zbootstrap.go | 15 - .../google/gops/internal/objfile/disasm.go | 283 -- .../github.com/google/gops/internal/objfile/elf.go | 124 - .../google/gops/internal/objfile/goobj.go | 160 - .../google/gops/internal/objfile/macho.go | 134 - .../google/gops/internal/objfile/objfile.go | 129 - .../github.com/google/gops/internal/objfile/pe.go | 208 - .../google/gops/internal/objfile/plan9obj.go | 156 - vendor/github.com/google/gops/internal/sys/arch.go | 161 - 69 files changed, 46227 deletions(-) delete mode 100644 vendor/github.com/google/gops/internal/LICENSE delete mode 100644 vendor/github.com/google/gops/internal/dwarf/dwarf.go delete mode 100644 vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go delete mode 100644 vendor/github.com/google/gops/internal/goobj/read.go delete mode 100644 vendor/github.com/google/gops/internal/obj/addrtype_string.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/anames5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/asm5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/list5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/obj5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/anames7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/asm7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/list7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/obj7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/data.go delete mode 100644 vendor/github.com/google/gops/internal/obj/flag.go delete mode 100644 vendor/github.com/google/gops/internal/obj/funcdata.go delete mode 100644 vendor/github.com/google/gops/internal/obj/go.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ld.go delete mode 100644 vendor/github.com/google/gops/internal/obj/link.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/anames0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/asm0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/list0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/obj0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/obj.go delete mode 100644 vendor/github.com/google/gops/internal/obj/objfile.go delete mode 100644 vendor/github.com/google/gops/internal/obj/pass.go delete mode 100644 vendor/github.com/google/gops/internal/obj/pcln.go delete mode 100644 vendor/github.com/google/gops/internal/obj/plist.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/anames9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/asm9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/list9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/obj9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/reloctype_string.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/anamesz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/asmz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/listz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/objz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/vector.go delete mode 100644 vendor/github.com/google/gops/internal/obj/stack.go delete mode 100644 vendor/github.com/google/gops/internal/obj/stringer.go delete mode 100644 vendor/github.com/google/gops/internal/obj/sym.go delete mode 100644 vendor/github.com/google/gops/internal/obj/symkind_string.go delete mode 100644 vendor/github.com/google/gops/internal/obj/textflag.go delete mode 100644 vendor/github.com/google/gops/internal/obj/typekind.go delete mode 100644 vendor/github.com/google/gops/internal/obj/util.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/asm6.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/list6.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/obj6.go delete mode 100644 vendor/github.com/google/gops/internal/obj/zbootstrap.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/disasm.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/elf.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/goobj.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/macho.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/objfile.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/pe.go delete mode 100644 vendor/github.com/google/gops/internal/objfile/plan9obj.go delete mode 100644 vendor/github.com/google/gops/internal/sys/arch.go (limited to 'vendor/github.com/google/gops/internal') diff --git a/vendor/github.com/google/gops/internal/LICENSE b/vendor/github.com/google/gops/internal/LICENSE deleted file mode 100644 index 55e52a01..00000000 --- a/vendor/github.com/google/gops/internal/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2016 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/gops/internal/dwarf/dwarf.go b/vendor/github.com/google/gops/internal/dwarf/dwarf.go deleted file mode 100644 index c72ef5b0..00000000 --- a/vendor/github.com/google/gops/internal/dwarf/dwarf.go +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright 2016 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 dwarf generates DWARF debugging information. -// DWARF generation is split between the compiler and the linker, -// this package contains the shared code. -package dwarf - -import ( - "fmt" -) - -// InfoPrefix is the prefix for all the symbols containing DWARF info entries. -const InfoPrefix = "go.info." - -// Sym represents a symbol. -type Sym interface { -} - -// A Var represents a local variable or a function parameter. -type Var struct { - Name string - Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM - Offset int32 - Type Sym - Link *Var -} - -// A Context specifies how to add data to a Sym. -type Context interface { - PtrSize() int - AddInt(s Sym, size int, i int64) - AddBytes(s Sym, b []byte) - AddAddress(s Sym, t interface{}, ofs int64) - AddSectionOffset(s Sym, size int, t interface{}, ofs int64) - AddString(s Sym, v string) - SymValue(s Sym) int64 -} - -// AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding. -func AppendUleb128(b []byte, v uint64) []byte { - for { - c := uint8(v & 0x7f) - v >>= 7 - if v != 0 { - c |= 0x80 - } - b = append(b, c) - if c&0x80 == 0 { - break - } - } - return b -} - -// AppendSleb128 appends v to b using DWARF's signed LEB128 encoding. -func AppendSleb128(b []byte, v int64) []byte { - for { - c := uint8(v & 0x7f) - s := uint8(v & 0x40) - v >>= 7 - if (v != -1 || s == 0) && (v != 0 || s != 0) { - c |= 0x80 - } - b = append(b, c) - if c&0x80 == 0 { - break - } - } - return b -} - -var encbuf [20]byte - -// AppendUleb128 appends v to s using DWARF's unsigned LEB128 encoding. -func Uleb128put(ctxt Context, s Sym, v int64) { - b := AppendUleb128(encbuf[:0], uint64(v)) - ctxt.AddBytes(s, b) -} - -// AppendUleb128 appends v to s using DWARF's signed LEB128 encoding. -func Sleb128put(ctxt Context, s Sym, v int64) { - b := AppendSleb128(encbuf[:0], v) - ctxt.AddBytes(s, b) -} - -/* - * Defining Abbrevs. This is hardcoded, and there will be - * only a handful of them. The DWARF spec places no restriction on - * the ordering of attributes in the Abbrevs and DIEs, and we will - * always write them out in the order of declaration in the abbrev. - */ -type dwAttrForm struct { - attr uint16 - form uint8 -} - -// Go-specific type attributes. -const ( - DW_AT_go_kind = 0x2900 - DW_AT_go_key = 0x2901 - DW_AT_go_elem = 0x2902 - - DW_AT_internal_location = 253 // params and locals; not emitted -) - -// Index into the abbrevs table below. -// Keep in sync with ispubname() and ispubtype() below. -// ispubtype considers >= NULLTYPE public -const ( - DW_ABRV_NULL = iota - DW_ABRV_COMPUNIT - DW_ABRV_FUNCTION - DW_ABRV_VARIABLE - DW_ABRV_AUTO - DW_ABRV_PARAM - DW_ABRV_STRUCTFIELD - DW_ABRV_FUNCTYPEPARAM - DW_ABRV_DOTDOTDOT - DW_ABRV_ARRAYRANGE - DW_ABRV_NULLTYPE - DW_ABRV_BASETYPE - DW_ABRV_ARRAYTYPE - DW_ABRV_CHANTYPE - DW_ABRV_FUNCTYPE - DW_ABRV_IFACETYPE - DW_ABRV_MAPTYPE - DW_ABRV_PTRTYPE - DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6. - DW_ABRV_SLICETYPE - DW_ABRV_STRINGTYPE - DW_ABRV_STRUCTTYPE - DW_ABRV_TYPEDECL - DW_NABRV -) - -type dwAbbrev struct { - tag uint8 - children uint8 - attr []dwAttrForm -} - -var abbrevs = [DW_NABRV]dwAbbrev{ - /* The mandatory DW_ABRV_NULL entry. */ - {0, 0, []dwAttrForm{}}, - - /* COMPUNIT */ - { - DW_TAG_compile_unit, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_language, DW_FORM_data1}, - {DW_AT_low_pc, DW_FORM_addr}, - {DW_AT_high_pc, DW_FORM_addr}, - {DW_AT_stmt_list, DW_FORM_data4}, - {DW_AT_comp_dir, DW_FORM_string}, - }, - }, - - /* FUNCTION */ - { - DW_TAG_subprogram, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_low_pc, DW_FORM_addr}, - {DW_AT_high_pc, DW_FORM_addr}, - {DW_AT_external, DW_FORM_flag}, - }, - }, - - /* VARIABLE */ - { - DW_TAG_variable, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_location, DW_FORM_block1}, - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_external, DW_FORM_flag}, - }, - }, - - /* AUTO */ - { - DW_TAG_variable, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_location, DW_FORM_block1}, - {DW_AT_type, DW_FORM_ref_addr}, - }, - }, - - /* PARAM */ - { - DW_TAG_formal_parameter, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_location, DW_FORM_block1}, - {DW_AT_type, DW_FORM_ref_addr}, - }, - }, - - /* STRUCTFIELD */ - { - DW_TAG_member, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_data_member_location, DW_FORM_block1}, - {DW_AT_type, DW_FORM_ref_addr}, - }, - }, - - /* FUNCTYPEPARAM */ - { - DW_TAG_formal_parameter, - DW_CHILDREN_no, - - // No name! - []dwAttrForm{ - {DW_AT_type, DW_FORM_ref_addr}, - }, - }, - - /* DOTDOTDOT */ - { - DW_TAG_unspecified_parameters, - DW_CHILDREN_no, - []dwAttrForm{}, - }, - - /* ARRAYRANGE */ - { - DW_TAG_subrange_type, - DW_CHILDREN_no, - - // No name! - []dwAttrForm{ - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_count, DW_FORM_udata}, - }, - }, - - // Below here are the types considered public by ispubtype - /* NULLTYPE */ - { - DW_TAG_unspecified_type, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - }, - }, - - /* BASETYPE */ - { - DW_TAG_base_type, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_encoding, DW_FORM_data1}, - {DW_AT_byte_size, DW_FORM_data1}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* ARRAYTYPE */ - // child is subrange with upper bound - { - DW_TAG_array_type, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_byte_size, DW_FORM_udata}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* CHANTYPE */ - { - DW_TAG_typedef, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_go_kind, DW_FORM_data1}, - {DW_AT_go_elem, DW_FORM_ref_addr}, - }, - }, - - /* FUNCTYPE */ - { - DW_TAG_subroutine_type, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - // {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* IFACETYPE */ - { - DW_TAG_typedef, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* MAPTYPE */ - { - DW_TAG_typedef, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_go_kind, DW_FORM_data1}, - {DW_AT_go_key, DW_FORM_ref_addr}, - {DW_AT_go_elem, DW_FORM_ref_addr}, - }, - }, - - /* PTRTYPE */ - { - DW_TAG_pointer_type, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_type, DW_FORM_ref_addr}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* BARE_PTRTYPE */ - { - DW_TAG_pointer_type, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - }, - }, - - /* SLICETYPE */ - { - DW_TAG_structure_type, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_byte_size, DW_FORM_udata}, - {DW_AT_go_kind, DW_FORM_data1}, - {DW_AT_go_elem, DW_FORM_ref_addr}, - }, - }, - - /* STRINGTYPE */ - { - DW_TAG_structure_type, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_byte_size, DW_FORM_udata}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* STRUCTTYPE */ - { - DW_TAG_structure_type, - DW_CHILDREN_yes, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_byte_size, DW_FORM_udata}, - {DW_AT_go_kind, DW_FORM_data1}, - }, - }, - - /* TYPEDECL */ - { - DW_TAG_typedef, - DW_CHILDREN_no, - []dwAttrForm{ - {DW_AT_name, DW_FORM_string}, - {DW_AT_type, DW_FORM_ref_addr}, - }, - }, -} - -// GetAbbrev returns the contents of the .debug_abbrev section. -func GetAbbrev() []byte { - var buf []byte - for i := 1; i < DW_NABRV; i++ { - // See section 7.5.3 - buf = AppendUleb128(buf, uint64(i)) - - buf = AppendUleb128(buf, uint64(abbrevs[i].tag)) - buf = append(buf, byte(abbrevs[i].children)) - for _, f := range abbrevs[i].attr { - buf = AppendUleb128(buf, uint64(f.attr)) - buf = AppendUleb128(buf, uint64(f.form)) - } - buf = append(buf, 0, 0) - } - return append(buf, 0) -} - -/* - * Debugging Information Entries and their attributes. - */ - -// DWAttr represents an attribute of a DWDie. -// -// For DW_CLS_string and _block, value should contain the length, and -// data the data, for _reference, value is 0 and data is a DWDie* to -// the referenced instance, for all others, value is the whole thing -// and data is null. -type DWAttr struct { - Link *DWAttr - Atr uint16 // DW_AT_ - Cls uint8 // DW_CLS_ - Value int64 - Data interface{} -} - -// DWDie represents a DWARF debug info entry. -type DWDie struct { - Abbrev int - Link *DWDie - Child *DWDie - Attr *DWAttr - Sym Sym -} - -func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error { - switch form { - case DW_FORM_addr: // address - ctxt.AddAddress(s, data, value) - - case DW_FORM_block1: // block - if cls == DW_CLS_ADDRESS { - ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize())) - ctxt.AddInt(s, 1, DW_OP_addr) - ctxt.AddAddress(s, data, 0) - break - } - - value &= 0xff - ctxt.AddInt(s, 1, value) - p := data.([]byte)[:value] - ctxt.AddBytes(s, p) - - case DW_FORM_block2: // block - value &= 0xffff - - ctxt.AddInt(s, 2, value) - p := data.([]byte)[:value] - ctxt.AddBytes(s, p) - - case DW_FORM_block4: // block - value &= 0xffffffff - - ctxt.AddInt(s, 4, value) - p := data.([]byte)[:value] - ctxt.AddBytes(s, p) - - case DW_FORM_block: // block - Uleb128put(ctxt, s, value) - - p := data.([]byte)[:value] - ctxt.AddBytes(s, p) - - case DW_FORM_data1: // constant - ctxt.AddInt(s, 1, value) - - case DW_FORM_data2: // constant - ctxt.AddInt(s, 2, value) - - case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr - if cls == DW_CLS_PTR { // DW_AT_stmt_list - ctxt.AddSectionOffset(s, 4, data, 0) - break - } - ctxt.AddInt(s, 4, value) - - case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr - ctxt.AddInt(s, 8, value) - - case DW_FORM_sdata: // constant - Sleb128put(ctxt, s, value) - - case DW_FORM_udata: // constant - Uleb128put(ctxt, s, value) - - case DW_FORM_string: // string - str := data.(string) - ctxt.AddString(s, str) - // TODO(ribrdb): verify padded strings are never used and remove this - for i := int64(len(str)); i < value; i++ { - ctxt.AddInt(s, 1, 0) - } - - case DW_FORM_flag: // flag - if value != 0 { - ctxt.AddInt(s, 1, 1) - } else { - ctxt.AddInt(s, 1, 0) - } - - // In DWARF 2 (which is what we claim to generate), - // the ref_addr is the same size as a normal address. - // In DWARF 3 it is always 32 bits, unless emitting a large - // (> 4 GB of debug info aka "64-bit") unit, which we don't implement. - case DW_FORM_ref_addr: // reference to a DIE in the .info section - if data == nil { - return fmt.Errorf("dwarf: null reference in %d", abbrev) - } else { - ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, 0) - } - - case DW_FORM_ref1, // reference within the compilation unit - DW_FORM_ref2, // reference - DW_FORM_ref4, // reference - DW_FORM_ref8, // reference - DW_FORM_ref_udata, // reference - - DW_FORM_strp, // string - DW_FORM_indirect: // (see Section 7.5.3) - fallthrough - default: - return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls) - } - return nil -} - -// PutAttrs writes the attributes for a DIE to symbol 's'. -// -// Note that we can (and do) add arbitrary attributes to a DIE, but -// only the ones actually listed in the Abbrev will be written out. -func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) { -Outer: - for _, f := range abbrevs[abbrev].attr { - for ap := attr; ap != nil; ap = ap.Link { - if ap.Atr == f.attr { - putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data) - continue Outer - } - } - - putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil) - } -} - -// HasChildren returns true if 'die' uses an abbrev that supports children. -func HasChildren(die *DWDie) bool { - return abbrevs[die.Abbrev].children != 0 -} - -// PutFunc writes a DIE for a function to s. -// It also writes child DIEs for each variable in vars. -func PutFunc(ctxt Context, s Sym, name string, external bool, startPC Sym, size int64, vars *Var) { - Uleb128put(ctxt, s, DW_ABRV_FUNCTION) - putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name) - putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC) - putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, size+ctxt.SymValue(startPC), startPC) - var ev int64 - if external { - ev = 1 - } - putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0) - names := make(map[string]bool) - for v := vars; v != nil; v = v.Link { - var n string - if names[v.Name] { - n = fmt.Sprintf("%s#%d", v.Name, len(names)) - } else { - n = v.Name - } - names[n] = true - - Uleb128put(ctxt, s, int64(v.Abbrev)) - putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n) - loc := append(encbuf[:0], DW_OP_call_frame_cfa) - if v.Offset != 0 { - loc = append(loc, DW_OP_consts) - loc = AppendSleb128(loc, int64(v.Offset)) - loc = append(loc, DW_OP_plus) - } - putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc) - putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type) - - } - Uleb128put(ctxt, s, 0) -} diff --git a/vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go b/vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go deleted file mode 100644 index d1870b57..00000000 --- a/vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright 2010 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 dwarf - -// Cut, pasted, tr-and-awk'ed from tables in -// http://dwarfstd.org/doc/Dwarf3.pdf - -// Table 18 -const ( - DW_TAG_array_type = 0x01 - DW_TAG_class_type = 0x02 - DW_TAG_entry_point = 0x03 - DW_TAG_enumeration_type = 0x04 - DW_TAG_formal_parameter = 0x05 - DW_TAG_imported_declaration = 0x08 - DW_TAG_label = 0x0a - DW_TAG_lexical_block = 0x0b - DW_TAG_member = 0x0d - DW_TAG_pointer_type = 0x0f - DW_TAG_reference_type = 0x10 - DW_TAG_compile_unit = 0x11 - DW_TAG_string_type = 0x12 - DW_TAG_structure_type = 0x13 - DW_TAG_subroutine_type = 0x15 - DW_TAG_typedef = 0x16 - DW_TAG_union_type = 0x17 - DW_TAG_unspecified_parameters = 0x18 - DW_TAG_variant = 0x19 - DW_TAG_common_block = 0x1a - DW_TAG_common_inclusion = 0x1b - DW_TAG_inheritance = 0x1c - DW_TAG_inlined_subroutine = 0x1d - DW_TAG_module = 0x1e - DW_TAG_ptr_to_member_type = 0x1f - DW_TAG_set_type = 0x20 - DW_TAG_subrange_type = 0x21 - DW_TAG_with_stmt = 0x22 - DW_TAG_access_declaration = 0x23 - DW_TAG_base_type = 0x24 - DW_TAG_catch_block = 0x25 - DW_TAG_const_type = 0x26 - DW_TAG_constant = 0x27 - DW_TAG_enumerator = 0x28 - DW_TAG_file_type = 0x29 - DW_TAG_friend = 0x2a - DW_TAG_namelist = 0x2b - DW_TAG_namelist_item = 0x2c - DW_TAG_packed_type = 0x2d - DW_TAG_subprogram = 0x2e - DW_TAG_template_type_parameter = 0x2f - DW_TAG_template_value_parameter = 0x30 - DW_TAG_thrown_type = 0x31 - DW_TAG_try_block = 0x32 - DW_TAG_variant_part = 0x33 - DW_TAG_variable = 0x34 - DW_TAG_volatile_type = 0x35 - // Dwarf3 - DW_TAG_dwarf_procedure = 0x36 - DW_TAG_restrict_type = 0x37 - DW_TAG_interface_type = 0x38 - DW_TAG_namespace = 0x39 - DW_TAG_imported_module = 0x3a - DW_TAG_unspecified_type = 0x3b - DW_TAG_partial_unit = 0x3c - DW_TAG_imported_unit = 0x3d - DW_TAG_condition = 0x3f - DW_TAG_shared_type = 0x40 - // Dwarf4 - DW_TAG_type_unit = 0x41 - DW_TAG_rvalue_reference_type = 0x42 - DW_TAG_template_alias = 0x43 - - // User defined - DW_TAG_lo_user = 0x4080 - DW_TAG_hi_user = 0xffff -) - -// Table 19 -const ( - DW_CHILDREN_no = 0x00 - DW_CHILDREN_yes = 0x01 -) - -// Not from the spec, but logically belongs here -const ( - DW_CLS_ADDRESS = 0x01 + iota - DW_CLS_BLOCK - DW_CLS_CONSTANT - DW_CLS_FLAG - DW_CLS_PTR // lineptr, loclistptr, macptr, rangelistptr - DW_CLS_REFERENCE - DW_CLS_ADDRLOC - DW_CLS_STRING -) - -// Table 20 -const ( - DW_AT_sibling = 0x01 // reference - DW_AT_location = 0x02 // block, loclistptr - DW_AT_name = 0x03 // string - DW_AT_ordering = 0x09 // constant - DW_AT_byte_size = 0x0b // block, constant, reference - DW_AT_bit_offset = 0x0c // block, constant, reference - DW_AT_bit_size = 0x0d // block, constant, reference - DW_AT_stmt_list = 0x10 // lineptr - DW_AT_low_pc = 0x11 // address - DW_AT_high_pc = 0x12 // address - DW_AT_language = 0x13 // constant - DW_AT_discr = 0x15 // reference - DW_AT_discr_value = 0x16 // constant - DW_AT_visibility = 0x17 // constant - DW_AT_import = 0x18 // reference - DW_AT_string_length = 0x19 // block, loclistptr - DW_AT_common_reference = 0x1a // reference - DW_AT_comp_dir = 0x1b // string - DW_AT_const_value = 0x1c // block, constant, string - DW_AT_containing_type = 0x1d // reference - DW_AT_default_value = 0x1e // reference - DW_AT_inline = 0x20 // constant - DW_AT_is_optional = 0x21 // flag - DW_AT_lower_bound = 0x22 // block, constant, reference - DW_AT_producer = 0x25 // string - DW_AT_prototyped = 0x27 // flag - DW_AT_return_addr = 0x2a // block, loclistptr - DW_AT_start_scope = 0x2c // constant - DW_AT_bit_stride = 0x2e // constant - DW_AT_upper_bound = 0x2f // block, constant, reference - DW_AT_abstract_origin = 0x31 // reference - DW_AT_accessibility = 0x32 // constant - DW_AT_address_class = 0x33 // constant - DW_AT_artificial = 0x34 // flag - DW_AT_base_types = 0x35 // reference - DW_AT_calling_convention = 0x36 // constant - DW_AT_count = 0x37 // block, constant, reference - DW_AT_data_member_location = 0x38 // block, constant, loclistptr - DW_AT_decl_column = 0x39 // constant - DW_AT_decl_file = 0x3a // constant - DW_AT_decl_line = 0x3b // constant - DW_AT_declaration = 0x3c // flag - DW_AT_discr_list = 0x3d // block - DW_AT_encoding = 0x3e // constant - DW_AT_external = 0x3f // flag - DW_AT_frame_base = 0x40 // block, loclistptr - DW_AT_friend = 0x41 // reference - DW_AT_identifier_case = 0x42 // constant - DW_AT_macro_info = 0x43 // macptr - DW_AT_namelist_item = 0x44 // block - DW_AT_priority = 0x45 // reference - DW_AT_segment = 0x46 // block, loclistptr - DW_AT_specification = 0x47 // reference - DW_AT_static_link = 0x48 // block, loclistptr - DW_AT_type = 0x49 // reference - DW_AT_use_location = 0x4a // block, loclistptr - DW_AT_variable_parameter = 0x4b // flag - DW_AT_virtuality = 0x4c // constant - DW_AT_vtable_elem_location = 0x4d // block, loclistptr - // Dwarf3 - DW_AT_allocated = 0x4e // block, constant, reference - DW_AT_associated = 0x4f // block, constant, reference - DW_AT_data_location = 0x50 // block - DW_AT_byte_stride = 0x51 // block, constant, reference - DW_AT_entry_pc = 0x52 // address - DW_AT_use_UTF8 = 0x53 // flag - DW_AT_extension = 0x54 // reference - DW_AT_ranges = 0x55 // rangelistptr - DW_AT_trampoline = 0x56 // address, flag, reference, string - DW_AT_call_column = 0x57 // constant - DW_AT_call_file = 0x58 // constant - DW_AT_call_line = 0x59 // constant - DW_AT_description = 0x5a // string - DW_AT_binary_scale = 0x5b // constant - DW_AT_decimal_scale = 0x5c // constant - DW_AT_small = 0x5d // reference - DW_AT_decimal_sign = 0x5e // constant - DW_AT_digit_count = 0x5f // constant - DW_AT_picture_string = 0x60 // string - DW_AT_mutable = 0x61 // flag - DW_AT_threads_scaled = 0x62 // flag - DW_AT_explicit = 0x63 // flag - DW_AT_object_pointer = 0x64 // reference - DW_AT_endianity = 0x65 // constant - DW_AT_elemental = 0x66 // flag - DW_AT_pure = 0x67 // flag - DW_AT_recursive = 0x68 // flag - - DW_AT_lo_user = 0x2000 // --- - DW_AT_hi_user = 0x3fff // --- -) - -// Table 21 -const ( - DW_FORM_addr = 0x01 // address - DW_FORM_block2 = 0x03 // block - DW_FORM_block4 = 0x04 // block - DW_FORM_data2 = 0x05 // constant - DW_FORM_data4 = 0x06 // constant, lineptr, loclistptr, macptr, rangelistptr - DW_FORM_data8 = 0x07 // constant, lineptr, loclistptr, macptr, rangelistptr - DW_FORM_string = 0x08 // string - DW_FORM_block = 0x09 // block - DW_FORM_block1 = 0x0a // block - DW_FORM_data1 = 0x0b // constant - DW_FORM_flag = 0x0c // flag - DW_FORM_sdata = 0x0d // constant - DW_FORM_strp = 0x0e // string - DW_FORM_udata = 0x0f // constant - DW_FORM_ref_addr = 0x10 // reference - DW_FORM_ref1 = 0x11 // reference - DW_FORM_ref2 = 0x12 // reference - DW_FORM_ref4 = 0x13 // reference - DW_FORM_ref8 = 0x14 // reference - DW_FORM_ref_udata = 0x15 // reference - DW_FORM_indirect = 0x16 // (see Section 7.5.3) -) - -// Table 24 (#operands, notes) -const ( - DW_OP_addr = 0x03 // 1 constant address (size target specific) - DW_OP_deref = 0x06 // 0 - DW_OP_const1u = 0x08 // 1 1-byte constant - DW_OP_const1s = 0x09 // 1 1-byte constant - DW_OP_const2u = 0x0a // 1 2-byte constant - DW_OP_const2s = 0x0b // 1 2-byte constant - DW_OP_const4u = 0x0c // 1 4-byte constant - DW_OP_const4s = 0x0d // 1 4-byte constant - DW_OP_const8u = 0x0e // 1 8-byte constant - DW_OP_const8s = 0x0f // 1 8-byte constant - DW_OP_constu = 0x10 // 1 ULEB128 constant - DW_OP_consts = 0x11 // 1 SLEB128 constant - DW_OP_dup = 0x12 // 0 - DW_OP_drop = 0x13 // 0 - DW_OP_over = 0x14 // 0 - DW_OP_pick = 0x15 // 1 1-byte stack index - DW_OP_swap = 0x16 // 0 - DW_OP_rot = 0x17 // 0 - DW_OP_xderef = 0x18 // 0 - DW_OP_abs = 0x19 // 0 - DW_OP_and = 0x1a // 0 - DW_OP_div = 0x1b // 0 - DW_OP_minus = 0x1c // 0 - DW_OP_mod = 0x1d // 0 - DW_OP_mul = 0x1e // 0 - DW_OP_neg = 0x1f // 0 - DW_OP_not = 0x20 // 0 - DW_OP_or = 0x21 // 0 - DW_OP_plus = 0x22 // 0 - DW_OP_plus_uconst = 0x23 // 1 ULEB128 addend - DW_OP_shl = 0x24 // 0 - DW_OP_shr = 0x25 // 0 - DW_OP_shra = 0x26 // 0 - DW_OP_xor = 0x27 // 0 - DW_OP_skip = 0x2f // 1 signed 2-byte constant - DW_OP_bra = 0x28 // 1 signed 2-byte constant - DW_OP_eq = 0x29 // 0 - DW_OP_ge = 0x2a // 0 - DW_OP_gt = 0x2b // 0 - DW_OP_le = 0x2c // 0 - DW_OP_lt = 0x2d // 0 - DW_OP_ne = 0x2e // 0 - DW_OP_lit0 = 0x30 // 0 ... - DW_OP_lit31 = 0x4f // 0 literals 0..31 = (DW_OP_lit0 + literal) - DW_OP_reg0 = 0x50 // 0 .. - DW_OP_reg31 = 0x6f // 0 reg 0..31 = (DW_OP_reg0 + regnum) - DW_OP_breg0 = 0x70 // 1 ... - DW_OP_breg31 = 0x8f // 1 SLEB128 offset base register 0..31 = (DW_OP_breg0 + regnum) - DW_OP_regx = 0x90 // 1 ULEB128 register - DW_OP_fbreg = 0x91 // 1 SLEB128 offset - DW_OP_bregx = 0x92 // 2 ULEB128 register followed by SLEB128 offset - DW_OP_piece = 0x93 // 1 ULEB128 size of piece addressed - DW_OP_deref_size = 0x94 // 1 1-byte size of data retrieved - DW_OP_xderef_size = 0x95 // 1 1-byte size of data retrieved - DW_OP_nop = 0x96 // 0 - DW_OP_push_object_address = 0x97 // 0 - DW_OP_call2 = 0x98 // 1 2-byte offset of DIE - DW_OP_call4 = 0x99 // 1 4-byte offset of DIE - DW_OP_call_ref = 0x9a // 1 4- or 8-byte offset of DIE - DW_OP_form_tls_address = 0x9b // 0 - DW_OP_call_frame_cfa = 0x9c // 0 - DW_OP_bit_piece = 0x9d // 2 - DW_OP_lo_user = 0xe0 - DW_OP_hi_user = 0xff -) - -// Table 25 -const ( - DW_ATE_address = 0x01 - DW_ATE_boolean = 0x02 - DW_ATE_complex_float = 0x03 - DW_ATE_float = 0x04 - DW_ATE_signed = 0x05 - DW_ATE_signed_char = 0x06 - DW_ATE_unsigned = 0x07 - DW_ATE_unsigned_char = 0x08 - DW_ATE_imaginary_float = 0x09 - DW_ATE_packed_decimal = 0x0a - DW_ATE_numeric_string = 0x0b - DW_ATE_edited = 0x0c - DW_ATE_signed_fixed = 0x0d - DW_ATE_unsigned_fixed = 0x0e - DW_ATE_decimal_float = 0x0f - DW_ATE_lo_user = 0x80 - DW_ATE_hi_user = 0xff -) - -// Table 26 -const ( - DW_DS_unsigned = 0x01 - DW_DS_leading_overpunch = 0x02 - DW_DS_trailing_overpunch = 0x03 - DW_DS_leading_separate = 0x04 - DW_DS_trailing_separate = 0x05 -) - -// Table 27 -const ( - DW_END_default = 0x00 - DW_END_big = 0x01 - DW_END_little = 0x02 - DW_END_lo_user = 0x40 - DW_END_hi_user = 0xff -) - -// Table 28 -const ( - DW_ACCESS_public = 0x01 - DW_ACCESS_protected = 0x02 - DW_ACCESS_private = 0x03 -) - -// Table 29 -const ( - DW_VIS_local = 0x01 - DW_VIS_exported = 0x02 - DW_VIS_qualified = 0x03 -) - -// Table 30 -const ( - DW_VIRTUALITY_none = 0x00 - DW_VIRTUALITY_virtual = 0x01 - DW_VIRTUALITY_pure_virtual = 0x02 -) - -// Table 31 -const ( - DW_LANG_C89 = 0x0001 - DW_LANG_C = 0x0002 - DW_LANG_Ada83 = 0x0003 - DW_LANG_C_plus_plus = 0x0004 - DW_LANG_Cobol74 = 0x0005 - DW_LANG_Cobol85 = 0x0006 - DW_LANG_Fortran77 = 0x0007 - DW_LANG_Fortran90 = 0x0008 - DW_LANG_Pascal83 = 0x0009 - DW_LANG_Modula2 = 0x000a - // Dwarf3 - DW_LANG_Java = 0x000b - DW_LANG_C99 = 0x000c - DW_LANG_Ada95 = 0x000d - DW_LANG_Fortran95 = 0x000e - DW_LANG_PLI = 0x000f - DW_LANG_ObjC = 0x0010 - DW_LANG_ObjC_plus_plus = 0x0011 - DW_LANG_UPC = 0x0012 - DW_LANG_D = 0x0013 - // Dwarf4 - DW_LANG_Python = 0x0014 - // Dwarf5 - DW_LANG_Go = 0x0016 - - DW_LANG_lo_user = 0x8000 - DW_LANG_hi_user = 0xffff -) - -// Table 32 -const ( - DW_ID_case_sensitive = 0x00 - DW_ID_up_case = 0x01 - DW_ID_down_case = 0x02 - DW_ID_case_insensitive = 0x03 -) - -// Table 33 -const ( - DW_CC_normal = 0x01 - DW_CC_program = 0x02 - DW_CC_nocall = 0x03 - DW_CC_lo_user = 0x40 - DW_CC_hi_user = 0xff -) - -// Table 34 -const ( - DW_INL_not_inlined = 0x00 - DW_INL_inlined = 0x01 - DW_INL_declared_not_inlined = 0x02 - DW_INL_declared_inlined = 0x03 -) - -// Table 35 -const ( - DW_ORD_row_major = 0x00 - DW_ORD_col_major = 0x01 -) - -// Table 36 -const ( - DW_DSC_label = 0x00 - DW_DSC_range = 0x01 -) - -// Table 37 -const ( - DW_LNS_copy = 0x01 - DW_LNS_advance_pc = 0x02 - DW_LNS_advance_line = 0x03 - DW_LNS_set_file = 0x04 - DW_LNS_set_column = 0x05 - DW_LNS_negate_stmt = 0x06 - DW_LNS_set_basic_block = 0x07 - DW_LNS_const_add_pc = 0x08 - DW_LNS_fixed_advance_pc = 0x09 - // Dwarf3 - DW_LNS_set_prologue_end = 0x0a - DW_LNS_set_epilogue_begin = 0x0b - DW_LNS_set_isa = 0x0c -) - -// Table 38 -const ( - DW_LNE_end_sequence = 0x01 - DW_LNE_set_address = 0x02 - DW_LNE_define_file = 0x03 - DW_LNE_lo_user = 0x80 - DW_LNE_hi_user = 0xff -) - -// Table 39 -const ( - DW_MACINFO_define = 0x01 - DW_MACINFO_undef = 0x02 - DW_MACINFO_start_file = 0x03 - DW_MACINFO_end_file = 0x04 - DW_MACINFO_vendor_ext = 0xff -) - -// Table 40. -const ( - // operand,... - DW_CFA_nop = 0x00 - DW_CFA_set_loc = 0x01 // address - DW_CFA_advance_loc1 = 0x02 // 1-byte delta - DW_CFA_advance_loc2 = 0x03 // 2-byte delta - DW_CFA_advance_loc4 = 0x04 // 4-byte delta - DW_CFA_offset_extended = 0x05 // ULEB128 register, ULEB128 offset - DW_CFA_restore_extended = 0x06 // ULEB128 register - DW_CFA_undefined = 0x07 // ULEB128 register - DW_CFA_same_value = 0x08 // ULEB128 register - DW_CFA_register = 0x09 // ULEB128 register, ULEB128 register - DW_CFA_remember_state = 0x0a - DW_CFA_restore_state = 0x0b - - DW_CFA_def_cfa = 0x0c // ULEB128 register, ULEB128 offset - DW_CFA_def_cfa_register = 0x0d // ULEB128 register - DW_CFA_def_cfa_offset = 0x0e // ULEB128 offset - DW_CFA_def_cfa_expression = 0x0f // BLOCK - DW_CFA_expression = 0x10 // ULEB128 register, BLOCK - DW_CFA_offset_extended_sf = 0x11 // ULEB128 register, SLEB128 offset - DW_CFA_def_cfa_sf = 0x12 // ULEB128 register, SLEB128 offset - DW_CFA_def_cfa_offset_sf = 0x13 // SLEB128 offset - DW_CFA_val_offset = 0x14 // ULEB128, ULEB128 - DW_CFA_val_offset_sf = 0x15 // ULEB128, SLEB128 - DW_CFA_val_expression = 0x16 // ULEB128, BLOCK - - DW_CFA_lo_user = 0x1c - DW_CFA_hi_user = 0x3f - - // Opcodes that take an addend operand. - DW_CFA_advance_loc = 0x1 << 6 // +delta - DW_CFA_offset = 0x2 << 6 // +register (ULEB128 offset) - DW_CFA_restore = 0x3 << 6 // +register -) diff --git a/vendor/github.com/google/gops/internal/goobj/read.go b/vendor/github.com/google/gops/internal/goobj/read.go deleted file mode 100644 index 8a6f13bc..00000000 --- a/vendor/github.com/google/gops/internal/goobj/read.go +++ /dev/null @@ -1,714 +0,0 @@ -// Copyright 2013 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 goobj implements reading of Go object files and archives. -// -// TODO(rsc): Decide where this package should live. (golang.org/issue/6932) -// TODO(rsc): Decide the appropriate integer types for various fields. -// TODO(rsc): Write tests. (File format still up in the air a little.) -package goobj - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "strconv" - "strings" - - "github.com/google/gops/internal/obj" -) - -// A SymKind describes the kind of memory represented by a symbol. -type SymKind int - -// This list is taken from include/link.h. - -// Defined SymKind values. -// TODO(rsc): Give idiomatic Go names. -// TODO(rsc): Reduce the number of symbol types in the object files. -const ( - // readonly, executable - STEXT = SymKind(obj.STEXT) - SELFRXSECT = SymKind(obj.SELFRXSECT) - - // readonly, non-executable - STYPE = SymKind(obj.STYPE) - SSTRING = SymKind(obj.SSTRING) - SGOSTRING = SymKind(obj.SGOSTRING) - SGOFUNC = SymKind(obj.SGOFUNC) - SRODATA = SymKind(obj.SRODATA) - SFUNCTAB = SymKind(obj.SFUNCTAB) - STYPELINK = SymKind(obj.STYPELINK) - SITABLINK = SymKind(obj.SITABLINK) - SSYMTAB = SymKind(obj.SSYMTAB) // TODO: move to unmapped section - SPCLNTAB = SymKind(obj.SPCLNTAB) - SELFROSECT = SymKind(obj.SELFROSECT) - - // writable, non-executable - SMACHOPLT = SymKind(obj.SMACHOPLT) - SELFSECT = SymKind(obj.SELFSECT) - SMACHO = SymKind(obj.SMACHO) // Mach-O __nl_symbol_ptr - SMACHOGOT = SymKind(obj.SMACHOGOT) - SWINDOWS = SymKind(obj.SWINDOWS) - SELFGOT = SymKind(obj.SELFGOT) - SNOPTRDATA = SymKind(obj.SNOPTRDATA) - SINITARR = SymKind(obj.SINITARR) - SDATA = SymKind(obj.SDATA) - SBSS = SymKind(obj.SBSS) - SNOPTRBSS = SymKind(obj.SNOPTRBSS) - STLSBSS = SymKind(obj.STLSBSS) - - // not mapped - SXREF = SymKind(obj.SXREF) - SMACHOSYMSTR = SymKind(obj.SMACHOSYMSTR) - SMACHOSYMTAB = SymKind(obj.SMACHOSYMTAB) - SMACHOINDIRECTPLT = SymKind(obj.SMACHOINDIRECTPLT) - SMACHOINDIRECTGOT = SymKind(obj.SMACHOINDIRECTGOT) - SFILE = SymKind(obj.SFILE) - SFILEPATH = SymKind(obj.SFILEPATH) - SCONST = SymKind(obj.SCONST) - SDYNIMPORT = SymKind(obj.SDYNIMPORT) - SHOSTOBJ = SymKind(obj.SHOSTOBJ) -) - -var symKindStrings = []string{ - SBSS: "SBSS", - SCONST: "SCONST", - SDATA: "SDATA", - SDYNIMPORT: "SDYNIMPORT", - SELFROSECT: "SELFROSECT", - SELFRXSECT: "SELFRXSECT", - SELFSECT: "SELFSECT", - SFILE: "SFILE", - SFILEPATH: "SFILEPATH", - SFUNCTAB: "SFUNCTAB", - SGOFUNC: "SGOFUNC", - SGOSTRING: "SGOSTRING", - SHOSTOBJ: "SHOSTOBJ", - SINITARR: "SINITARR", - SMACHO: "SMACHO", - SMACHOGOT: "SMACHOGOT", - SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT", - SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT", - SMACHOPLT: "SMACHOPLT", - SMACHOSYMSTR: "SMACHOSYMSTR", - SMACHOSYMTAB: "SMACHOSYMTAB", - SNOPTRBSS: "SNOPTRBSS", - SNOPTRDATA: "SNOPTRDATA", - SPCLNTAB: "SPCLNTAB", - SRODATA: "SRODATA", - SSTRING: "SSTRING", - SSYMTAB: "SSYMTAB", - STEXT: "STEXT", - STLSBSS: "STLSBSS", - STYPE: "STYPE", - STYPELINK: "STYPELINK", - SITABLINK: "SITABLINK", - SWINDOWS: "SWINDOWS", - SXREF: "SXREF", -} - -func (k SymKind) String() string { - if k < 0 || int(k) >= len(symKindStrings) { - return fmt.Sprintf("SymKind(%d)", k) - } - return symKindStrings[k] -} - -// A Sym is a named symbol in an object file. -type Sym struct { - SymID // symbol identifier (name and version) - Kind SymKind // kind of symbol - DupOK bool // are duplicate definitions okay? - Size int // size of corresponding data - Type SymID // symbol for Go type information - Data Data // memory image of symbol - Reloc []Reloc // relocations to apply to Data - Func *Func // additional data for functions -} - -// A SymID - the combination of Name and Version - uniquely identifies -// a symbol within a package. -type SymID struct { - // Name is the name of a symbol. - Name string - - // Version is zero for symbols with global visibility. - // Symbols with only file visibility (such as file-level static - // declarations in C) have a non-zero version distinguishing - // a symbol in one file from a symbol of the same name - // in another file - Version int -} - -func (s SymID) String() string { - if s.Version == 0 { - return s.Name - } - return fmt.Sprintf("%s<%d>", s.Name, s.Version) -} - -// A Data is a reference to data stored in an object file. -// It records the offset and size of the data, so that a client can -// read the data only if necessary. -type Data struct { - Offset int64 - Size int64 -} - -// A Reloc describes a relocation applied to a memory image to refer -// to an address within a particular symbol. -type Reloc struct { - // The bytes at [Offset, Offset+Size) within the containing Sym - // should be updated to refer to the address Add bytes after the start - // of the symbol Sym. - Offset int - Size int - Sym SymID - Add int - - // The Type records the form of address expected in the bytes - // described by the previous fields: absolute, PC-relative, and so on. - // TODO(rsc): The interpretation of Type is not exposed by this package. - Type obj.RelocType -} - -// A Var describes a variable in a function stack frame: a declared -// local variable, an input argument, or an output result. -type Var struct { - // The combination of Name, Kind, and Offset uniquely - // identifies a variable in a function stack frame. - // Using fewer of these - in particular, using only Name - does not. - Name string // Name of variable. - Kind int // TODO(rsc): Define meaning. - Offset int // Frame offset. TODO(rsc): Define meaning. - - Type SymID // Go type for variable. -} - -// Func contains additional per-symbol information specific to functions. -type Func struct { - Args int // size in bytes of argument frame: inputs and outputs - Frame int // size in bytes of local variable frame - Leaf bool // function omits save of link register (ARM) - NoSplit bool // function omits stack split prologue - Var []Var // detail about local variables - PCSP Data // PC → SP offset map - PCFile Data // PC → file number map (index into File) - PCLine Data // PC → line number map - PCData []Data // PC → runtime support data map - FuncData []FuncData // non-PC-specific runtime support data - File []string // paths indexed by PCFile -} - -// TODO: Add PCData []byte and PCDataIter (similar to liblink). - -// A FuncData is a single function-specific data value. -type FuncData struct { - Sym SymID // symbol holding data - Offset int64 // offset into symbol for funcdata pointer -} - -// A Package is a parsed Go object file or archive defining a Go package. -type Package struct { - ImportPath string // import path denoting this package - Imports []string // packages imported by this package - SymRefs []SymID // list of symbol names and versions referred to by this pack - Syms []*Sym // symbols defined by this package - MaxVersion int // maximum Version in any SymID in Syms - Arch string // architecture -} - -var ( - archiveHeader = []byte("!\n") - archiveMagic = []byte("`\n") - goobjHeader = []byte("go objec") // truncated to size of archiveHeader - - errCorruptArchive = errors.New("corrupt archive") - errTruncatedArchive = errors.New("truncated archive") - errCorruptObject = errors.New("corrupt object file") - errNotObject = errors.New("unrecognized object file format") -) - -// An objReader is an object file reader. -type objReader struct { - p *Package - b *bufio.Reader - f io.ReadSeeker - err error - offset int64 - dataOffset int64 - limit int64 - tmp [256]byte - pkgprefix string -} - -// importPathToPrefix returns the prefix that will be used in the -// final symbol table for the given import path. -// We escape '%', '"', all control characters and non-ASCII bytes, -// and any '.' after the final slash. -// -// See ../../../cmd/ld/lib.c:/^pathtoprefix and -// ../../../cmd/gc/subr.c:/^pathtoprefix. -func importPathToPrefix(s string) string { - // find index of last slash, if any, or else -1. - // used for determining whether an index is after the last slash. - slash := strings.LastIndex(s, "/") - - // check for chars that need escaping - n := 0 - for r := 0; r < len(s); r++ { - if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { - n++ - } - } - - // quick exit - if n == 0 { - return s - } - - // escape - const hex = "0123456789abcdef" - p := make([]byte, 0, len(s)+2*n) - for r := 0; r < len(s); r++ { - if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { - p = append(p, '%', hex[c>>4], hex[c&0xF]) - } else { - p = append(p, c) - } - } - - return string(p) -} - -// init initializes r to read package p from f. -func (r *objReader) init(f io.ReadSeeker, p *Package) { - r.f = f - r.p = p - r.offset, _ = f.Seek(0, io.SeekCurrent) - r.limit, _ = f.Seek(0, io.SeekEnd) - f.Seek(r.offset, io.SeekStart) - r.b = bufio.NewReader(f) - r.pkgprefix = importPathToPrefix(p.ImportPath) + "." -} - -// error records that an error occurred. -// It returns only the first error, so that an error -// caused by an earlier error does not discard information -// about the earlier error. -func (r *objReader) error(err error) error { - if r.err == nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - r.err = err - } - // panic("corrupt") // useful for debugging - return r.err -} - -// readByte reads and returns a byte from the input file. -// On I/O error or EOF, it records the error but returns byte 0. -// A sequence of 0 bytes will eventually terminate any -// parsing state in the object file. In particular, it ends the -// reading of a varint. -func (r *objReader) readByte() byte { - if r.err != nil { - return 0 - } - if r.offset >= r.limit { - r.error(io.ErrUnexpectedEOF) - return 0 - } - b, err := r.b.ReadByte() - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - r.error(err) - b = 0 - } else { - r.offset++ - } - return b -} - -// read reads exactly len(b) bytes from the input file. -// If an error occurs, read returns the error but also -// records it, so it is safe for callers to ignore the result -// as long as delaying the report is not a problem. -func (r *objReader) readFull(b []byte) error { - if r.err != nil { - return r.err - } - if r.offset+int64(len(b)) > r.limit { - return r.error(io.ErrUnexpectedEOF) - } - n, err := io.ReadFull(r.b, b) - r.offset += int64(n) - if err != nil { - return r.error(err) - } - return nil -} - -// readInt reads a zigzag varint from the input file. -func (r *objReader) readInt() int { - var u uint64 - - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - r.error(errCorruptObject) - return 0 - } - c := r.readByte() - u |= uint64(c&0x7F) << shift - if c&0x80 == 0 { - break - } - } - - v := int64(u>>1) ^ (int64(u) << 63 >> 63) - if int64(int(v)) != v { - r.error(errCorruptObject) // TODO - return 0 - } - return int(v) -} - -// readString reads a length-delimited string from the input file. -func (r *objReader) readString() string { - n := r.readInt() - buf := make([]byte, n) - r.readFull(buf) - return string(buf) -} - -// readSymID reads a SymID from the input file. -func (r *objReader) readSymID() SymID { - i := r.readInt() - return r.p.SymRefs[i] -} - -func (r *objReader) readRef() { - name, vers := r.readString(), r.readInt() - - // In a symbol name in an object file, "". denotes the - // prefix for the package in which the object file has been found. - // Expand it. - name = strings.Replace(name, `"".`, r.pkgprefix, -1) - - // An individual object file only records version 0 (extern) or 1 (static). - // To make static symbols unique across all files being read, we - // replace version 1 with the version corresponding to the current - // file number. The number is incremented on each call to parseObject. - if vers != 0 { - vers = r.p.MaxVersion - } - r.p.SymRefs = append(r.p.SymRefs, SymID{name, vers}) -} - -// readData reads a data reference from the input file. -func (r *objReader) readData() Data { - n := r.readInt() - d := Data{Offset: r.dataOffset, Size: int64(n)} - r.dataOffset += int64(n) - return d -} - -// skip skips n bytes in the input. -func (r *objReader) skip(n int64) { - if n < 0 { - r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip")) - } - if n < int64(len(r.tmp)) { - // Since the data is so small, a just reading from the buffered - // reader is better than flushing the buffer and seeking. - r.readFull(r.tmp[:n]) - } else if n <= int64(r.b.Buffered()) { - // Even though the data is not small, it has already been read. - // Advance the buffer instead of seeking. - for n > int64(len(r.tmp)) { - r.readFull(r.tmp[:]) - n -= int64(len(r.tmp)) - } - r.readFull(r.tmp[:n]) - } else { - // Seek, giving up buffered data. - _, err := r.f.Seek(r.offset+n, io.SeekStart) - if err != nil { - r.error(err) - } - r.offset += n - r.b.Reset(r.f) - } -} - -// Parse parses an object file or archive from r, -// assuming that its import path is pkgpath. -func Parse(r io.ReadSeeker, pkgpath string) (*Package, error) { - if pkgpath == "" { - pkgpath = `""` - } - p := new(Package) - p.ImportPath = pkgpath - - var rd objReader - rd.init(r, p) - err := rd.readFull(rd.tmp[:8]) - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - return nil, err - } - - switch { - default: - return nil, errNotObject - - case bytes.Equal(rd.tmp[:8], archiveHeader): - if err := rd.parseArchive(); err != nil { - return nil, err - } - case bytes.Equal(rd.tmp[:8], goobjHeader): - if err := rd.parseObject(goobjHeader); err != nil { - return nil, err - } - } - - return p, nil -} - -// trimSpace removes trailing spaces from b and returns the corresponding string. -// This effectively parses the form used in archive headers. -func trimSpace(b []byte) string { - return string(bytes.TrimRight(b, " ")) -} - -// parseArchive parses a Unix archive of Go object files. -// TODO(rsc): Need to skip non-Go object files. -// TODO(rsc): Maybe record table of contents in r.p so that -// linker can avoid having code to parse archives too. -func (r *objReader) parseArchive() error { - for r.offset < r.limit { - if err := r.readFull(r.tmp[:60]); err != nil { - return err - } - data := r.tmp[:60] - - // Each file is preceded by this text header (slice indices in first column): - // 0:16 name - // 16:28 date - // 28:34 uid - // 34:40 gid - // 40:48 mode - // 48:58 size - // 58:60 magic - `\n - // We only care about name, size, and magic. - // The fields are space-padded on the right. - // The size is in decimal. - // The file data - size bytes - follows the header. - // Headers are 2-byte aligned, so if size is odd, an extra padding - // byte sits between the file data and the next header. - // The file data that follows is padded to an even number of bytes: - // if size is odd, an extra padding byte is inserted betw the next header. - if len(data) < 60 { - return errTruncatedArchive - } - if !bytes.Equal(data[58:60], archiveMagic) { - return errCorruptArchive - } - name := trimSpace(data[0:16]) - size, err := strconv.ParseInt(trimSpace(data[48:58]), 10, 64) - if err != nil { - return errCorruptArchive - } - data = data[60:] - fsize := size + size&1 - if fsize < 0 || fsize < size { - return errCorruptArchive - } - switch name { - case "__.PKGDEF": - r.skip(size) - default: - oldLimit := r.limit - r.limit = r.offset + size - if err := r.parseObject(nil); err != nil { - return fmt.Errorf("parsing archive member %q: %v", name, err) - } - r.skip(r.limit - r.offset) - r.limit = oldLimit - } - if size&1 != 0 { - r.skip(1) - } - } - return nil -} - -// parseObject parses a single Go object file. -// The prefix is the bytes already read from the file, -// typically in order to detect that this is an object file. -// The object file consists of a textual header ending in "\n!\n" -// and then the part we want to parse begins. -// The format of that part is defined in a comment at the top -// of src/liblink/objfile.c. -func (r *objReader) parseObject(prefix []byte) error { - r.p.MaxVersion++ - h := make([]byte, 0, 256) - h = append(h, prefix...) - var c1, c2, c3 byte - for { - c1, c2, c3 = c2, c3, r.readByte() - h = append(h, c3) - // The new export format can contain 0 bytes. - // Don't consider them errors, only look for r.err != nil. - if r.err != nil { - return errCorruptObject - } - if c1 == '\n' && c2 == '!' && c3 == '\n' { - break - } - } - - hs := strings.Fields(string(h)) - if len(hs) >= 4 { - r.p.Arch = hs[3] - } - // TODO: extract OS + build ID if/when we need it - - r.readFull(r.tmp[:8]) - if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go17ld")) { - return r.error(errCorruptObject) - } - - b := r.readByte() - if b != 1 { - return r.error(errCorruptObject) - } - - // Direct package dependencies. - for { - s := r.readString() - if s == "" { - break - } - r.p.Imports = append(r.p.Imports, s) - } - - r.p.SymRefs = []SymID{{"", 0}} - for { - if b := r.readByte(); b != 0xfe { - if b != 0xff { - return r.error(errCorruptObject) - } - break - } - - r.readRef() - } - - dataLength := r.readInt() - r.readInt() // n relocations - ignore - r.readInt() // n pcdata - ignore - r.readInt() // n autom - ignore - r.readInt() // n funcdata - ignore - r.readInt() // n files - ignore - - r.dataOffset = r.offset - r.skip(int64(dataLength)) - - // Symbols. - for { - if b := r.readByte(); b != 0xfe { - if b != 0xff { - return r.error(errCorruptObject) - } - break - } - - typ := r.readInt() - s := &Sym{SymID: r.readSymID()} - r.p.Syms = append(r.p.Syms, s) - s.Kind = SymKind(typ) - flags := r.readInt() - s.DupOK = flags&1 != 0 - s.Size = r.readInt() - s.Type = r.readSymID() - s.Data = r.readData() - s.Reloc = make([]Reloc, r.readInt()) - for i := range s.Reloc { - rel := &s.Reloc[i] - rel.Offset = r.readInt() - rel.Size = r.readInt() - rel.Type = obj.RelocType(r.readInt()) - rel.Add = r.readInt() - rel.Sym = r.readSymID() - } - - if s.Kind == STEXT { - f := new(Func) - s.Func = f - f.Args = r.readInt() - f.Frame = r.readInt() - flags := r.readInt() - f.Leaf = flags&1 != 0 - f.NoSplit = r.readInt() != 0 - f.Var = make([]Var, r.readInt()) - for i := range f.Var { - v := &f.Var[i] - v.Name = r.readSymID().Name - v.Offset = r.readInt() - v.Kind = r.readInt() - v.Type = r.readSymID() - } - - f.PCSP = r.readData() - f.PCFile = r.readData() - f.PCLine = r.readData() - f.PCData = make([]Data, r.readInt()) - for i := range f.PCData { - f.PCData[i] = r.readData() - } - f.FuncData = make([]FuncData, r.readInt()) - for i := range f.FuncData { - f.FuncData[i].Sym = r.readSymID() - } - for i := range f.FuncData { - f.FuncData[i].Offset = int64(r.readInt()) // TODO - } - f.File = make([]string, r.readInt()) - for i := range f.File { - f.File[i] = r.readSymID().Name - } - } - } - - r.readFull(r.tmp[:7]) - if !bytes.Equal(r.tmp[:7], []byte("\xffgo17ld")) { - return r.error(errCorruptObject) - } - - return nil -} - -func (r *Reloc) String(insnOffset uint64) string { - delta := r.Offset - int(insnOffset) - s := fmt.Sprintf("[%d:%d]%s", delta, delta+r.Size, r.Type) - if r.Sym.Name != "" { - if r.Add != 0 { - return fmt.Sprintf("%s:%s+%d", s, r.Sym.Name, r.Add) - } - return fmt.Sprintf("%s:%s", s, r.Sym.Name) - } - if r.Add != 0 { - return fmt.Sprintf("%s:%d", s, r.Add) - } - return s -} diff --git a/vendor/github.com/google/gops/internal/obj/addrtype_string.go b/vendor/github.com/google/gops/internal/obj/addrtype_string.go deleted file mode 100644 index 48d498dc..00000000 --- a/vendor/github.com/google/gops/internal/obj/addrtype_string.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by "stringer -type AddrType cmd/internal/obj"; DO NOT EDIT - -package obj - -import "fmt" - -const ( - _AddrType_name_0 = "TYPE_NONE" - _AddrType_name_1 = "TYPE_BRANCHTYPE_TEXTSIZETYPE_MEMTYPE_CONSTTYPE_FCONSTTYPE_SCONSTTYPE_REGTYPE_ADDRTYPE_SHIFTTYPE_REGREGTYPE_REGREG2TYPE_INDIRTYPE_REGLIST" -) - -var ( - _AddrType_index_0 = [...]uint8{0, 9} - _AddrType_index_1 = [...]uint8{0, 11, 24, 32, 42, 53, 64, 72, 81, 91, 102, 114, 124, 136} -) - -func (i AddrType) String() string { - switch { - case i == 0: - return _AddrType_name_0 - case 6 <= i && i <= 18: - i -= 6 - return _AddrType_name_1[_AddrType_index_1[i]:_AddrType_index_1[i+1]] - default: - return fmt.Sprintf("AddrType(%d)", i) - } -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/a.out.go b/vendor/github.com/google/gops/internal/obj/arm/a.out.go deleted file mode 100644 index a3e0c180..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm/a.out.go +++ /dev/null @@ -1,338 +0,0 @@ -// Inferno utils/5c/5.out.h -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/5.out.h -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm - -import "github.com/google/gops/internal/obj" - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm - -const ( - NSNAME = 8 - NSYM = 50 - NREG = 16 -) - -/* -1 disables use of REGARG */ -const ( - REGARG = -1 -) - -const ( - REG_R0 = obj.RBaseARM + iota // must be 16-aligned - REG_R1 - REG_R2 - REG_R3 - REG_R4 - REG_R5 - REG_R6 - REG_R7 - REG_R8 - REG_R9 - REG_R10 - REG_R11 - REG_R12 - REG_R13 - REG_R14 - REG_R15 - - REG_F0 // must be 16-aligned - REG_F1 - REG_F2 - REG_F3 - REG_F4 - REG_F5 - REG_F6 - REG_F7 - REG_F8 - REG_F9 - REG_F10 - REG_F11 - REG_F12 - REG_F13 - REG_F14 - REG_F15 - - REG_FPSR // must be 2-aligned - REG_FPCR - - REG_CPSR // must be 2-aligned - REG_SPSR - - MAXREG - REGRET = REG_R0 - /* compiler allocates R1 up as temps */ - /* compiler allocates register variables R3 up */ - /* compiler allocates external registers R10 down */ - REGEXT = REG_R10 - /* these two registers are declared in runtime.h */ - REGG = REGEXT - 0 - REGM = REGEXT - 1 - - REGCTXT = REG_R7 - REGTMP = REG_R11 - REGSP = REG_R13 - REGLINK = REG_R14 - REGPC = REG_R15 - - NFREG = 16 - /* compiler allocates register variables F0 up */ - /* compiler allocates external registers F7 down */ - FREGRET = REG_F0 - FREGEXT = REG_F7 - FREGTMP = REG_F15 -) - -const ( - C_NONE = iota - C_REG - C_REGREG - C_REGREG2 - C_REGLIST - C_SHIFT - C_FREG - C_PSR - C_FCR - - C_RCON /* 0xff rotated */ - C_NCON /* ~RCON */ - C_SCON /* 0xffff */ - C_LCON - C_LCONADDR - C_ZFCON - C_SFCON - C_LFCON - - C_RACON - C_LACON - - C_SBRA - C_LBRA - - C_HAUTO /* halfword insn offset (-0xff to 0xff) */ - C_FAUTO /* float insn offset (0 to 0x3fc, word aligned) */ - C_HFAUTO /* both H and F */ - C_SAUTO /* -0xfff to 0xfff */ - C_LAUTO - - C_HOREG - C_FOREG - C_HFOREG - C_SOREG - C_ROREG - C_SROREG /* both nil and R */ - C_LOREG - - C_PC - C_SP - C_HREG - - C_ADDR /* reference to relocatable address */ - - // TLS "var" in local exec mode: will become a constant offset from - // thread local base that is ultimately chosen by the program linker. - C_TLS_LE - - // TLS "var" in initial exec mode: will become a memory address (chosen - // by the program linker) that the dynamic linker will fill with the - // offset from the thread local base. - C_TLS_IE - - C_TEXTSIZE - - C_GOK - - C_NCLASS /* must be the last */ -) - -const ( - AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota - AEOR - ASUB - ARSB - AADD - AADC - ASBC - ARSC - ATST - ATEQ - ACMP - ACMN - AORR - ABIC - - AMVN - - /* - * Do not reorder or fragment the conditional branch - * opcodes, or the predication code will break - */ - ABEQ - ABNE - ABCS - ABHS - ABCC - ABLO - ABMI - ABPL - ABVS - ABVC - ABHI - ABLS - ABGE - ABLT - ABGT - ABLE - - AMOVWD - AMOVWF - AMOVDW - AMOVFW - AMOVFD - AMOVDF - AMOVF - AMOVD - - ACMPF - ACMPD - AADDF - AADDD - ASUBF - ASUBD - AMULF - AMULD - ADIVF - ADIVD - ASQRTF - ASQRTD - AABSF - AABSD - ANEGF - ANEGD - - ASRL - ASRA - ASLL - AMULU - ADIVU - AMUL - ADIV - AMOD - AMODU - - AMOVB - AMOVBS - AMOVBU - AMOVH - AMOVHS - AMOVHU - AMOVW - AMOVM - ASWPBU - ASWPW - - ARFE - ASWI - AMULA - - AWORD - - AMULL - AMULAL - AMULLU - AMULALU - - ABX - ABXRET - ADWORD - - ALDREX - ASTREX - ALDREXD - ASTREXD - - APLD - - ACLZ - - AMULWT - AMULWB - AMULAWT - AMULAWB - - ADATABUNDLE - ADATABUNDLEEND - - AMRC // MRC/MCR - - ALAST - - // aliases - AB = obj.AJMP - ABL = obj.ACALL -) - -/* scond byte */ -const ( - C_SCOND = (1 << 4) - 1 - C_SBIT = 1 << 4 - C_PBIT = 1 << 5 - C_WBIT = 1 << 6 - C_FBIT = 1 << 7 /* psr flags-only */ - C_UBIT = 1 << 7 /* up bit, unsigned bit */ - - // These constants are the ARM condition codes encodings, - // XORed with 14 so that C_SCOND_NONE has value 0, - // so that a zeroed Prog.scond means "always execute". - C_SCOND_XOR = 14 - - C_SCOND_EQ = 0 ^ C_SCOND_XOR - C_SCOND_NE = 1 ^ C_SCOND_XOR - C_SCOND_HS = 2 ^ C_SCOND_XOR - C_SCOND_LO = 3 ^ C_SCOND_XOR - C_SCOND_MI = 4 ^ C_SCOND_XOR - C_SCOND_PL = 5 ^ C_SCOND_XOR - C_SCOND_VS = 6 ^ C_SCOND_XOR - C_SCOND_VC = 7 ^ C_SCOND_XOR - C_SCOND_HI = 8 ^ C_SCOND_XOR - C_SCOND_LS = 9 ^ C_SCOND_XOR - C_SCOND_GE = 10 ^ C_SCOND_XOR - C_SCOND_LT = 11 ^ C_SCOND_XOR - C_SCOND_GT = 12 ^ C_SCOND_XOR - C_SCOND_LE = 13 ^ C_SCOND_XOR - C_SCOND_NONE = 14 ^ C_SCOND_XOR - C_SCOND_NV = 15 ^ C_SCOND_XOR - - /* D_SHIFT type */ - SHIFT_LL = 0 << 5 - SHIFT_LR = 1 << 5 - SHIFT_AR = 2 << 5 - SHIFT_RR = 3 << 5 -) diff --git a/vendor/github.com/google/gops/internal/obj/arm/anames.go b/vendor/github.com/google/gops/internal/obj/arm/anames.go deleted file mode 100644 index 42abc946..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm/anames.go +++ /dev/null @@ -1,108 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p arm -// Do not edit. - -package arm - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "AND", - "EOR", - "SUB", - "RSB", - "ADD", - "ADC", - "SBC", - "RSC", - "TST", - "TEQ", - "CMP", - "CMN", - "ORR", - "BIC", - "MVN", - "BEQ", - "BNE", - "BCS", - "BHS", - "BCC", - "BLO", - "BMI", - "BPL", - "BVS", - "BVC", - "BHI", - "BLS", - "BGE", - "BLT", - "BGT", - "BLE", - "MOVWD", - "MOVWF", - "MOVDW", - "MOVFW", - "MOVFD", - "MOVDF", - "MOVF", - "MOVD", - "CMPF", - "CMPD", - "ADDF", - "ADDD", - "SUBF", - "SUBD", - "MULF", - "MULD", - "DIVF", - "DIVD", - "SQRTF", - "SQRTD", - "ABSF", - "ABSD", - "NEGF", - "NEGD", - "SRL", - "SRA", - "SLL", - "MULU", - "DIVU", - "MUL", - "DIV", - "MOD", - "MODU", - "MOVB", - "MOVBS", - "MOVBU", - "MOVH", - "MOVHS", - "MOVHU", - "MOVW", - "MOVM", - "SWPBU", - "SWPW", - "RFE", - "SWI", - "MULA", - "WORD", - "MULL", - "MULAL", - "MULLU", - "MULALU", - "BX", - "BXRET", - "DWORD", - "LDREX", - "STREX", - "LDREXD", - "STREXD", - "PLD", - "CLZ", - "MULWT", - "MULWB", - "MULAWT", - "MULAWB", - "DATABUNDLE", - "DATABUNDLEEND", - "MRC", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/anames5.go b/vendor/github.com/google/gops/internal/obj/arm/anames5.go deleted file mode 100644 index 7fdd9623..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm/anames5.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 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 arm - -var cnames5 = []string{ - "NONE", - "REG", - "REGREG", - "REGREG2", - "REGLIST", - "SHIFT", - "FREG", - "PSR", - "FCR", - "RCON", - "NCON", - "SCON", - "LCON", - "LCONADDR", - "ZFCON", - "SFCON", - "LFCON", - "RACON", - "LACON", - "SBRA", - "LBRA", - "HAUTO", - "FAUTO", - "HFAUTO", - "SAUTO", - "LAUTO", - "HOREG", - "FOREG", - "HFOREG", - "SOREG", - "ROREG", - "SROREG", - "LOREG", - "PC", - "SP", - "HREG", - "ADDR", - "C_TLS_LE", - "C_TLS_IE", - "TEXTSIZE", - "GOK", - "NCLASS", - "SCOND = (1<<4)-1", - "SBIT = 1<<4", - "PBIT = 1<<5", - "WBIT = 1<<6", - "FBIT = 1<<7", - "UBIT = 1<<7", - "SCOND_XOR = 14", - "SCOND_EQ = 0 ^ C_SCOND_XOR", - "SCOND_NE = 1 ^ C_SCOND_XOR", - "SCOND_HS = 2 ^ C_SCOND_XOR", - "SCOND_LO = 3 ^ C_SCOND_XOR", - "SCOND_MI = 4 ^ C_SCOND_XOR", - "SCOND_PL = 5 ^ C_SCOND_XOR", - "SCOND_VS = 6 ^ C_SCOND_XOR", - "SCOND_VC = 7 ^ C_SCOND_XOR", - "SCOND_HI = 8 ^ C_SCOND_XOR", - "SCOND_LS = 9 ^ C_SCOND_XOR", - "SCOND_GE = 10 ^ C_SCOND_XOR", - "SCOND_LT = 11 ^ C_SCOND_XOR", - "SCOND_GT = 12 ^ C_SCOND_XOR", - "SCOND_LE = 13 ^ C_SCOND_XOR", - "SCOND_NONE = 14 ^ C_SCOND_XOR", - "SCOND_NV = 15 ^ C_SCOND_XOR", -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/asm5.go b/vendor/github.com/google/gops/internal/obj/arm/asm5.go deleted file mode 100644 index aa8149d5..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm/asm5.go +++ /dev/null @@ -1,2846 +0,0 @@ -// Inferno utils/5l/span.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm - -import ( - "fmt" - "log" - "math" - "sort" - - "github.com/google/gops/internal/obj" -) - -type Optab struct { - as obj.As - a1 uint8 - a2 int8 - a3 uint8 - type_ uint8 - size int8 - param int16 - flag int8 - pcrelsiz uint8 -} - -type Opcross [32][2][32]uint8 - -const ( - LFROM = 1 << 0 - LTO = 1 << 1 - LPOOL = 1 << 2 - LPCREL = 1 << 3 -) - -var optab = []Optab{ - /* struct Optab: - OPCODE, from, prog->reg, to, type,size,param,flag */ - {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0}, - {AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMVN, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0}, - {AADD, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0}, - {AADD, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0}, - {AMOVW, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0}, - {AMVN, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0}, - {ACMP, C_RCON, C_REG, C_NONE, 2, 4, 0, 0, 0}, - {AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0}, - {AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0}, - {AMOVW, C_RACON, C_NONE, C_REG, 4, 4, REGSP, 0, 0}, - {AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL, 0}, - {ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, - {ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0, 0, 0}, - {ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, - {ABEQ, C_RCON, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // prediction hinted form, hint ignored - - {AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL, 0}, - {ABL, C_NONE, C_NONE, C_ROREG, 7, 4, 0, 0, 0}, - {ABL, C_REG, C_NONE, C_ROREG, 7, 4, 0, 0, 0}, - {ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0, 0, 0}, - {ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0, 0, 0}, - {ASLL, C_RCON, C_REG, C_REG, 8, 4, 0, 0, 0}, - {ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0, 0, 0}, - {ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0}, - {ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0}, - {ASWI, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0}, - {ASWI, C_NONE, C_NONE, C_LOREG, 10, 4, 0, 0, 0}, - {ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_LCONADDR, 11, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_TLS_LE, 103, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_TLS_IE, 104, 4, 0, 0, 0}, - {AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0}, - {AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0}, - {AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4}, - {AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0}, - {AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, - {AMVN, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, - {ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0}, - {AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0}, - {AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0}, - {AMVN, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0}, - {ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0}, - {AMOVB, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMOVHS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0}, - {AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0}, - {AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0}, - {AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0}, - {ADIV, C_REG, C_REG, C_REG, 16, 4, 0, 0, 0}, - {ADIV, C_REG, C_NONE, C_REG, 16, 4, 0, 0, 0}, - {AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0, 0, 0}, - {AMULA, C_REG, C_REG, C_REGREG2, 17, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVW, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVW, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVBU, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVBU, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVBS, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVBS, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVBS, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVW, C_TLS_LE, C_NONE, C_REG, 101, 4, 0, LFROM, 0}, - {AMOVW, C_TLS_IE, C_NONE, C_REG, 102, 8, 0, LFROM, 0}, - {AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0}, - {AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0}, - {AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4}, - {AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0}, - {AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4}, - {AMOVW, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0}, - {AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_PSR, 36, 4, 0, 0, 0}, - {AMOVW, C_RCON, C_NONE, C_PSR, 37, 4, 0, 0, 0}, - {AMOVM, C_REGLIST, C_NONE, C_SOREG, 38, 4, 0, 0, 0}, - {AMOVM, C_SOREG, C_NONE, C_REGLIST, 39, 4, 0, 0, 0}, - {ASWPW, C_SOREG, C_REG, C_REG, 40, 4, 0, 0, 0}, - {ARFE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_FAUTO, 50, 4, REGSP, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_FOREG, 50, 4, 0, 0, 0}, - {AMOVF, C_FAUTO, C_NONE, C_FREG, 51, 4, REGSP, 0, 0}, - {AMOVF, C_FOREG, C_NONE, C_FREG, 51, 4, 0, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_LAUTO, 52, 12, REGSP, LTO, 0}, - {AMOVF, C_FREG, C_NONE, C_LOREG, 52, 12, 0, LTO, 0}, - {AMOVF, C_LAUTO, C_NONE, C_FREG, 53, 12, REGSP, LFROM, 0}, - {AMOVF, C_LOREG, C_NONE, C_FREG, 53, 12, 0, LFROM, 0}, - {AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4}, - {AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4}, - {AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0}, - {AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0}, - {AMOVW, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0}, - {AMOVBU, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0}, - {AMOVB, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0}, - {AMOVBS, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, - {AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, - {AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, - {AMOVHS, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, - {AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, - {AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, - {AMOVB, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVB, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVBS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVBS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVH, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVH, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVHS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVHS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVHU, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVHU, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0}, - {AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0}, - {AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4}, - {AMOVHS, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0}, - {AMOVHS, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0}, - {AMOVHS, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4}, - {AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0}, - {AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0}, - {AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4}, - {AMOVB, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVB, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVBS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVBS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVBS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVH, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVH, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVHS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVHS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVHS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVHU, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVHU, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0}, - {ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0}, - {AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0}, - {AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0}, - {ACMPF, C_FREG, C_REG, C_NONE, 82, 8, 0, 0, 0}, - {ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0}, - {AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0}, - {AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0}, - {AMOVFW, C_FREG, C_NONE, C_REG, 86, 8, 0, 0, 0}, - {AMOVWF, C_REG, C_NONE, C_FREG, 87, 8, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0, 0, 0}, - {AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0, 0, 0}, - {ATST, C_REG, C_NONE, C_NONE, 90, 4, 0, 0, 0}, - {ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0}, - {ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0}, - {APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0}, - {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0}, - {ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0}, - {AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0}, - {AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0}, - {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - {obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0}, - {obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0}, - {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - {obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL - {obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL - - {ADATABUNDLE, C_NONE, C_NONE, C_NONE, 100, 4, 0, 0, 0}, - {ADATABUNDLEEND, C_NONE, C_NONE, C_NONE, 100, 0, 0, 0, 0}, - {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0}, -} - -var pool struct { - start uint32 - size uint32 - extra uint32 -} - -var oprange [ALAST & obj.AMask][]Optab - -var xcmp [C_GOK + 1][C_GOK + 1]bool - -var deferreturn *obj.LSym - -// Note about encoding: Prog.scond holds the condition encoding, -// but XOR'ed with C_SCOND_XOR, so that C_SCOND_NONE == 0. -// The code that shifts the value << 28 has the responsibility -// for XORing with C_SCOND_XOR too. - -// asmoutnacl assembles the instruction p. It replaces asmout for NaCl. -// It returns the total number of bytes put in out, and it can change -// p->pc if extra padding is necessary. -// In rare cases, asmoutnacl might split p into two instructions. -// origPC is the PC for this Prog (no padding is taken into account). -func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint32) int { - size := int(o.size) - - // instruction specific - switch p.As { - default: - if out != nil { - asmout(ctxt, p, o, out) - } - - case ADATABUNDLE, // align to 16-byte boundary - ADATABUNDLEEND: // zero width instruction, just to align next instruction to 16-byte boundary - p.Pc = (p.Pc + 15) &^ 15 - - if out != nil { - asmout(ctxt, p, o, out) - } - - case obj.AUNDEF, - APLD: - size = 4 - if out != nil { - switch p.As { - case obj.AUNDEF: - out[0] = 0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0) - - case APLD: - out[0] = 0xe1a01001 // (MOVW R1, R1) - } - } - - case AB, ABL: - if p.To.Type != obj.TYPE_MEM { - if out != nil { - asmout(ctxt, p, o, out) - } - } else { - if p.To.Offset != 0 || size != 4 || p.To.Reg > REG_R15 || p.To.Reg < REG_R0 { - ctxt.Diag("unsupported instruction: %v", p) - } - if p.Pc&15 == 12 { - p.Pc += 4 - } - if out != nil { - out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c0013f | (uint32(p.To.Reg)&15)<<12 | (uint32(p.To.Reg)&15)<<16 // BIC $0xc000000f, Rx - if p.As == AB { - out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff10 | (uint32(p.To.Reg)&15)<<0 // BX Rx - } else { // ABL - out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff30 | (uint32(p.To.Reg)&15)<<0 // BLX Rx - } - } - - size = 8 - } - - // align the last instruction (the actual BL) to the last instruction in a bundle - if p.As == ABL { - if deferreturn == nil { - deferreturn = obj.Linklookup(ctxt, "runtime.deferreturn", 0) - } - if p.To.Sym == deferreturn { - p.Pc = ((int64(origPC) + 15) &^ 15) + 16 - int64(size) - } else { - p.Pc += (16 - ((p.Pc + int64(size)) & 15)) & 15 - } - } - - case ALDREX, - ALDREXD, - AMOVB, - AMOVBS, - AMOVBU, - AMOVD, - AMOVF, - AMOVH, - AMOVHS, - AMOVHU, - AMOVM, - AMOVW, - ASTREX, - ASTREXD: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_R15 && p.From.Reg == REG_R13 { // MOVW.W x(R13), PC - if out != nil { - asmout(ctxt, p, o, out) - } - if size == 4 { - if out != nil { - // Note: 5c and 5g reg.c know that DIV/MOD smashes R12 - // so that this return instruction expansion is valid. - out[0] = out[0] &^ 0x3000 // change PC to R12 - out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 - out[2] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff1c // BX R12 - } - - size += 8 - if (p.Pc+int64(size))&15 == 4 { - p.Pc += 4 - } - break - } else { - // if the instruction used more than 4 bytes, then it must have used a very large - // offset to update R13, so we need to additionally mask R13. - if out != nil { - out[size/4-1] &^= 0x3000 // change PC to R12 - out[size/4] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03cdd103 // BIC $0xc0000000, R13 - out[size/4+1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 - out[size/4+2] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff1c // BX R12 - } - - // p->pc+size is only ok at 4 or 12 mod 16. - if (p.Pc+int64(size))%8 == 0 { - p.Pc += 4 - } - size += 12 - break - } - } - - if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_R15 { - ctxt.Diag("unsupported instruction (move to another register and use indirect jump instead): %v", p) - } - - if p.To.Type == obj.TYPE_MEM && p.To.Reg == REG_R13 && (p.Scond&C_WBIT != 0) && size > 4 { - // function prolog with very large frame size: MOVW.W R14,-100004(R13) - // split it into two instructions: - // ADD $-100004, R13 - // MOVW R14, 0(R13) - q := ctxt.NewProg() - - p.Scond &^= C_WBIT - *q = *p - a := &p.To - var a2 *obj.Addr - if p.To.Type == obj.TYPE_MEM { - a2 = &q.To - } else { - a2 = &q.From - } - nocache(q) - nocache(p) - - // insert q after p - q.Link = p.Link - - p.Link = q - q.Pcond = nil - - // make p into ADD $X, R13 - p.As = AADD - - p.From = *a - p.From.Reg = 0 - p.From.Type = obj.TYPE_CONST - p.To = obj.Addr{} - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R13 - - // make q into p but load/store from 0(R13) - q.Spadj = 0 - - *a2 = obj.Addr{} - a2.Type = obj.TYPE_MEM - a2.Reg = REG_R13 - a2.Sym = nil - a2.Offset = 0 - size = int(oplook(ctxt, p).size) - break - } - - if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R9) || // MOVW Rx, X(Ry), y != 9 - (p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R9) { // MOVW X(Rx), Ry, x != 9 - var a *obj.Addr - if p.To.Type == obj.TYPE_MEM { - a = &p.To - } else { - a = &p.From - } - reg := int(a.Reg) - if size == 4 { - // if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify. - if reg == 0 { - if out != nil { - asmout(ctxt, p, o, out) - } - } else { - if out != nil { - out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c00103 | (uint32(reg)&15)<<16 | (uint32(reg)&15)<<12 // BIC $0xc0000000, Rx - } - if p.Pc&15 == 12 { - p.Pc += 4 - } - size += 4 - if out != nil { - asmout(ctxt, p, o, out[1:]) - } - } - - break - } else { - // if a load/store instruction takes more than 1 word to implement, then - // we need to separate the instruction into two: - // 1. explicitly load the address into R11. - // 2. load/store from R11. - // This won't handle .W/.P, so we should reject such code. - if p.Scond&(C_PBIT|C_WBIT) != 0 { - ctxt.Diag("unsupported instruction (.P/.W): %v", p) - } - q := ctxt.NewProg() - *q = *p - var a2 *obj.Addr - if p.To.Type == obj.TYPE_MEM { - a2 = &q.To - } else { - a2 = &q.From - } - nocache(q) - nocache(p) - - // insert q after p - q.Link = p.Link - - p.Link = q - q.Pcond = nil - - // make p into MOVW $X(R), R11 - p.As = AMOVW - - p.From = *a - p.From.Type = obj.TYPE_ADDR - p.To = obj.Addr{} - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R11 - - // make q into p but load/store from 0(R11) - *a2 = obj.Addr{} - - a2.Type = obj.TYPE_MEM - a2.Reg = REG_R11 - a2.Sym = nil - a2.Offset = 0 - size = int(oplook(ctxt, p).size) - break - } - } else if out != nil { - asmout(ctxt, p, o, out) - } - } - - // destination register specific - if p.To.Type == obj.TYPE_REG { - switch p.To.Reg { - case REG_R9: - ctxt.Diag("invalid instruction, cannot write to R9: %v", p) - - case REG_R13: - if out != nil { - out[size/4] = 0xe3cdd103 // BIC $0xc0000000, R13 - } - if (p.Pc+int64(size))&15 == 0 { - p.Pc += 4 - } - size += 4 - } - } - - return size -} - -func span5(ctxt *obj.Link, cursym *obj.LSym) { - var p *obj.Prog - var op *obj.Prog - - p = cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - - if oprange[AAND&obj.AMask] == nil { - buildop(ctxt) - } - - ctxt.Cursym = cursym - - ctxt.Autosize = int32(p.To.Offset + 4) - c := int32(0) - - op = p - p = p.Link - var i int - var m int - var o *Optab - for ; p != nil || ctxt.Blitrl != nil; op, p = p, p.Link { - if p == nil { - if checkpool(ctxt, op, 0) { - p = op - continue - } - - // can't happen: blitrl is not nil, but checkpool didn't flushpool - ctxt.Diag("internal inconsistency") - - break - } - - ctxt.Curp = p - p.Pc = int64(c) - o = oplook(ctxt, p) - if ctxt.Headtype != obj.Hnacl { - m = int(o.size) - } else { - m = asmoutnacl(ctxt, c, p, o, nil) - c = int32(p.Pc) // asmoutnacl might change pc for alignment - o = oplook(ctxt, p) // asmoutnacl might change p in rare cases - } - - if m%4 != 0 || p.Pc%4 != 0 { - ctxt.Diag("!pc invalid: %v size=%d", p, m) - } - - // must check literal pool here in case p generates many instructions - if ctxt.Blitrl != nil { - i = m - if checkpool(ctxt, op, i) { - p = op - continue - } - } - - if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP && p.As != obj.AUSEFIELD) { - ctxt.Diag("zero-width instruction\n%v", p) - continue - } - - switch o.flag & (LFROM | LTO | LPOOL) { - case LFROM: - addpool(ctxt, p, &p.From) - - case LTO: - addpool(ctxt, p, &p.To) - - case LPOOL: - if p.Scond&C_SCOND == C_SCOND_NONE { - flushpool(ctxt, p, 0, 0) - } - } - - if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE { - flushpool(ctxt, p, 0, 0) - } - c += int32(m) - } - - cursym.Size = int64(c) - - /* - * if any procedure is large enough to - * generate a large SBRA branch, then - * generate extra passes putting branches - * around jmps to fix. this is rare. - */ - times := 0 - - var bflag int - var opc int32 - var out [6 + 3]uint32 - for { - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f span1\n", obj.Cputime()) - } - bflag = 0 - c = 0 - times++ - cursym.Text.Pc = 0 // force re-layout the code. - for p = cursym.Text; p != nil; p = p.Link { - ctxt.Curp = p - o = oplook(ctxt, p) - if int64(c) > p.Pc { - p.Pc = int64(c) - } - - /* very large branches - if(o->type == 6 && p->pcond) { - otxt = p->pcond->pc - c; - if(otxt < 0) - otxt = -otxt; - if(otxt >= (1L<<17) - 10) { - q = emallocz(sizeof(Prog)); - q->link = p->link; - p->link = q; - q->as = AB; - q->to.type = TYPE_BRANCH; - q->pcond = p->pcond; - p->pcond = q; - q = emallocz(sizeof(Prog)); - q->link = p->link; - p->link = q; - q->as = AB; - q->to.type = TYPE_BRANCH; - q->pcond = q->link->link; - bflag = 1; - } - } - */ - opc = int32(p.Pc) - - if ctxt.Headtype != obj.Hnacl { - m = int(o.size) - } else { - m = asmoutnacl(ctxt, c, p, o, nil) - } - if p.Pc != int64(opc) { - bflag = 1 - } - - //print("%v pc changed %d to %d in iter. %d\n", p, opc, (int32)p->pc, times); - c = int32(p.Pc + int64(m)) - - if m%4 != 0 || p.Pc%4 != 0 { - ctxt.Diag("pc invalid: %v size=%d", p, m) - } - - if m/4 > len(out) { - ctxt.Diag("instruction size too large: %d > %d", m/4, len(out)) - } - if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP && p.As != obj.AUSEFIELD) { - if p.As == obj.ATEXT { - ctxt.Autosize = int32(p.To.Offset + 4) - continue - } - - ctxt.Diag("zero-width instruction\n%v", p) - continue - } - } - - cursym.Size = int64(c) - if bflag == 0 { - break - } - } - - if c%4 != 0 { - ctxt.Diag("sym->size=%d, invalid", c) - } - - /* - * lay out the code. all the pc-relative code references, - * even cross-function, are resolved now; - * only data references need to be relocated. - * with more work we could leave cross-function - * code references to be relocated too, and then - * perhaps we'd be able to parallelize the span loop above. - */ - - p = cursym.Text - ctxt.Autosize = int32(p.To.Offset + 4) - cursym.Grow(cursym.Size) - - bp := cursym.P - c = int32(p.Pc) // even p->link might need extra padding - var v int - for p = p.Link; p != nil; p = p.Link { - ctxt.Pc = p.Pc - ctxt.Curp = p - o = oplook(ctxt, p) - opc = int32(p.Pc) - if ctxt.Headtype != obj.Hnacl { - asmout(ctxt, p, o, out[:]) - m = int(o.size) - } else { - m = asmoutnacl(ctxt, c, p, o, out[:]) - if int64(opc) != p.Pc { - ctxt.Diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %v", opc, int32(p.Pc), p) - } - } - - if m%4 != 0 || p.Pc%4 != 0 { - ctxt.Diag("final stage: pc invalid: %v size=%d", p, m) - } - - if int64(c) > p.Pc { - ctxt.Diag("PC padding invalid: want %#d, has %#d: %v", p.Pc, c, p) - } - for int64(c) != p.Pc { - // emit 0xe1a00000 (MOVW R0, R0) - bp[0] = 0x00 - bp = bp[1:] - - bp[0] = 0x00 - bp = bp[1:] - bp[0] = 0xa0 - bp = bp[1:] - bp[0] = 0xe1 - bp = bp[1:] - c += 4 - } - - for i = 0; i < m/4; i++ { - v = int(out[i]) - bp[0] = byte(v) - bp = bp[1:] - bp[0] = byte(v >> 8) - bp = bp[1:] - bp[0] = byte(v >> 16) - bp = bp[1:] - bp[0] = byte(v >> 24) - bp = bp[1:] - } - - c += int32(m) - } -} - -/* - * when the first reference to the literal pool threatens - * to go out of range of a 12-bit PC-relative offset, - * drop the pool now, and branch round it. - * this happens only in extended basic blocks that exceed 4k. - */ -func checkpool(ctxt *obj.Link, p *obj.Prog, sz int) bool { - if pool.size >= 0xff0 || immaddr(int32((p.Pc+int64(sz)+4)+4+int64(12+pool.size)-int64(pool.start+8))) == 0 { - return flushpool(ctxt, p, 1, 0) - } else if p.Link == nil { - return flushpool(ctxt, p, 2, 0) - } - return false -} - -func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool { - if ctxt.Blitrl != nil { - if skip != 0 { - if false && skip == 1 { - fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start) - } - q := ctxt.NewProg() - q.As = AB - q.To.Type = obj.TYPE_BRANCH - q.Pcond = p.Link - q.Link = ctxt.Blitrl - q.Lineno = p.Lineno - ctxt.Blitrl = q - } else if force == 0 && (p.Pc+int64(12+pool.size)-int64(pool.start) < 2048) { // 12 take into account the maximum nacl literal pool alignment padding size - return false - } - if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 { - // if pool is not multiple of 16 bytes, add an alignment marker - q := ctxt.NewProg() - - q.As = ADATABUNDLEEND - ctxt.Elitrl.Link = q - ctxt.Elitrl = q - } - - // The line number for constant pool entries doesn't really matter. - // We set it to the line number of the preceding instruction so that - // there are no deltas to encode in the pc-line tables. - for q := ctxt.Blitrl; q != nil; q = q.Link { - q.Lineno = p.Lineno - } - - ctxt.Elitrl.Link = p.Link - p.Link = ctxt.Blitrl - - ctxt.Blitrl = nil /* BUG: should refer back to values until out-of-range */ - ctxt.Elitrl = nil - pool.size = 0 - pool.start = 0 - pool.extra = 0 - return true - } - - return false -} - -func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - var t obj.Prog - - c := aclass(ctxt, a) - - t.Ctxt = ctxt - t.As = AWORD - - switch c { - default: - t.To.Offset = a.Offset - t.To.Sym = a.Sym - t.To.Type = a.Type - t.To.Name = a.Name - - if ctxt.Flag_shared && t.To.Sym != nil { - t.Rel = p - } - - case C_SROREG, - C_LOREG, - C_ROREG, - C_FOREG, - C_SOREG, - C_HOREG, - C_FAUTO, - C_SAUTO, - C_LAUTO, - C_LACON: - t.To.Type = obj.TYPE_CONST - t.To.Offset = ctxt.Instoffset - } - - if t.Rel == nil { - for q := ctxt.Blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */ - if q.Rel == nil && q.To == t.To { - p.Pcond = q - return - } - } - } - - if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 { - // start a new data bundle - q := ctxt.NewProg() - q.As = ADATABUNDLE - q.Pc = int64(pool.size) - pool.size += 4 - if ctxt.Blitrl == nil { - ctxt.Blitrl = q - pool.start = uint32(p.Pc) - } else { - ctxt.Elitrl.Link = q - } - - ctxt.Elitrl = q - } - - q := ctxt.NewProg() - *q = t - q.Pc = int64(pool.size) - - if ctxt.Blitrl == nil { - ctxt.Blitrl = q - pool.start = uint32(p.Pc) - } else { - ctxt.Elitrl.Link = q - } - ctxt.Elitrl = q - pool.size += 4 - - p.Pcond = q -} - -func regoff(ctxt *obj.Link, a *obj.Addr) int32 { - ctxt.Instoffset = 0 - aclass(ctxt, a) - return int32(ctxt.Instoffset) -} - -func immrot(v uint32) int32 { - for i := 0; i < 16; i++ { - if v&^0xff == 0 { - return int32(uint32(int32(i)<<8) | v | 1<<25) - } - v = v<<2 | v>>30 - } - - return 0 -} - -func immaddr(v int32) int32 { - if v >= 0 && v <= 0xfff { - return v&0xfff | 1<<24 | 1<<23 /* pre indexing */ /* pre indexing, up */ - } - if v >= -0xfff && v < 0 { - return -v&0xfff | 1<<24 /* pre indexing */ - } - return 0 -} - -func immfloat(v int32) bool { - return v&0xC03 == 0 /* offset will fit in floating-point load/store */ -} - -func immhalf(v int32) bool { - if v >= 0 && v <= 0xff { - return v|1<<24|1<<23 != 0 /* pre indexing */ /* pre indexing, up */ - } - if v >= -0xff && v < 0 { - return -v&0xff|1<<24 != 0 /* pre indexing */ - } - return false -} - -func aclass(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return C_NONE - - case obj.TYPE_REG: - ctxt.Instoffset = 0 - if REG_R0 <= a.Reg && a.Reg <= REG_R15 { - return C_REG - } - if REG_F0 <= a.Reg && a.Reg <= REG_F15 { - return C_FREG - } - if a.Reg == REG_FPSR || a.Reg == REG_FPCR { - return C_FCR - } - if a.Reg == REG_CPSR || a.Reg == REG_SPSR { - return C_PSR - } - return C_GOK - - case obj.TYPE_REGREG: - return C_REGREG - - case obj.TYPE_REGREG2: - return C_REGREG2 - - case obj.TYPE_REGLIST: - return C_REGLIST - - case obj.TYPE_SHIFT: - return C_SHIFT - - case obj.TYPE_MEM: - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_GOTREF, - obj.NAME_STATIC: - if a.Sym == nil || a.Sym.Name == "" { - fmt.Printf("null sym external\n") - return C_GOK - } - - ctxt.Instoffset = 0 // s.b. unused but just in case - if a.Sym.Type == obj.STLSBSS { - if ctxt.Flag_shared { - return C_TLS_IE - } else { - return C_TLS_LE - } - } - - return C_ADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if t := immaddr(int32(ctxt.Instoffset)); t != 0 { - if immhalf(int32(ctxt.Instoffset)) { - if immfloat(t) { - return C_HFAUTO - } - return C_HAUTO - } - - if immfloat(t) { - return C_FAUTO - } - return C_SAUTO - } - - return C_LAUTO - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4 - if t := immaddr(int32(ctxt.Instoffset)); t != 0 { - if immhalf(int32(ctxt.Instoffset)) { - if immfloat(t) { - return C_HFAUTO - } - return C_HAUTO - } - - if immfloat(t) { - return C_FAUTO - } - return C_SAUTO - } - - return C_LAUTO - - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if t := immaddr(int32(ctxt.Instoffset)); t != 0 { - if immhalf(int32(ctxt.Instoffset)) { /* n.b. that it will also satisfy immrot */ - if immfloat(t) { - return C_HFOREG - } - return C_HOREG - } - - if immfloat(t) { - return C_FOREG /* n.b. that it will also satisfy immrot */ - } - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_SROREG - } - if immhalf(int32(ctxt.Instoffset)) { - return C_HOREG - } - return C_SOREG - } - - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_ROREG - } - return C_LOREG - } - - return C_GOK - - case obj.TYPE_FCONST: - if chipzero5(ctxt, a.Val.(float64)) >= 0 { - return C_ZFCON - } - if chipfloat5(ctxt, a.Val.(float64)) >= 0 { - return C_SFCON - } - return C_LFCON - - case obj.TYPE_TEXTSIZE: - return C_TEXTSIZE - - case obj.TYPE_CONST, - obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if a.Reg != 0 { - return aconsize(ctxt) - } - - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_RCON - } - if immrot(^uint32(ctxt.Instoffset)) != 0 { - return C_NCON - } - return C_LCON - - case obj.NAME_EXTERN, - obj.NAME_GOTREF, - obj.NAME_STATIC: - s := a.Sym - if s == nil { - break - } - ctxt.Instoffset = 0 // s.b. unused but just in case - return C_LCONADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - return aconsize(ctxt) - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4 - return aconsize(ctxt) - } - - return C_GOK - - case obj.TYPE_BRANCH: - return C_SBRA - } - - return C_GOK -} - -func aconsize(ctxt *obj.Link) int { - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_RACON - } - if immrot(uint32(-ctxt.Instoffset)) != 0 { - return C_RACON - } - return C_LACON -} - -func prasm(p *obj.Prog) { - fmt.Printf("%v\n", p) -} - -func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { - a1 := int(p.Optab) - if a1 != 0 { - return &optab[a1-1] - } - a1 = int(p.From.Class) - if a1 == 0 { - a1 = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(a1) - } - - a1-- - a3 := int(p.To.Class) - if a3 == 0 { - a3 = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(a3) - } - - a3-- - a2 := C_NONE - if p.Reg != 0 { - a2 = C_REG - } - - if false { /*debug['O']*/ - fmt.Printf("oplook %v %v %v %v\n", p.As, DRconv(a1), DRconv(a2), DRconv(a3)) - fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type) - } - - ops := oprange[p.As&obj.AMask] - c1 := &xcmp[a1] - c3 := &xcmp[a3] - for i := range ops { - op := &ops[i] - if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] { - p.Optab = uint16(cap(optab) - cap(ops) + i + 1) - return op - } - } - - ctxt.Diag("illegal combination %v; %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type) - ctxt.Diag("from %d %d to %d %d\n", p.From.Type, p.From.Name, p.To.Type, p.To.Name) - prasm(p) - if ops == nil { - ops = optab - } - return &ops[0] -} - -func cmp(a int, b int) bool { - if a == b { - return true - } - switch a { - case C_LCON: - if b == C_RCON || b == C_NCON { - return true - } - - case C_LACON: - if b == C_RACON { - return true - } - - case C_LFCON: - if b == C_ZFCON || b == C_SFCON { - return true - } - - case C_HFAUTO: - return b == C_HAUTO || b == C_FAUTO - - case C_FAUTO, C_HAUTO: - return b == C_HFAUTO - - case C_SAUTO: - return cmp(C_HFAUTO, b) - - case C_LAUTO: - return cmp(C_SAUTO, b) - - case C_HFOREG: - return b == C_HOREG || b == C_FOREG - - case C_FOREG, C_HOREG: - return b == C_HFOREG - - case C_SROREG: - return cmp(C_SOREG, b) || cmp(C_ROREG, b) - - case C_SOREG, C_ROREG: - return b == C_SROREG || cmp(C_HFOREG, b) - - case C_LOREG: - return cmp(C_SROREG, b) - - case C_LBRA: - if b == C_SBRA { - return true - } - - case C_HREG: - return cmp(C_SP, b) || cmp(C_PC, b) - } - - return false -} - -type ocmp []Optab - -func (x ocmp) Len() int { - return len(x) -} - -func (x ocmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x ocmp) Less(i, j int) bool { - p1 := &x[i] - p2 := &x[j] - n := int(p1.as) - int(p2.as) - if n != 0 { - return n < 0 - } - n = int(p1.a1) - int(p2.a1) - if n != 0 { - return n < 0 - } - n = int(p1.a2) - int(p2.a2) - if n != 0 { - return n < 0 - } - n = int(p1.a3) - int(p2.a3) - if n != 0 { - return n < 0 - } - return false -} - -func opset(a, b0 obj.As) { - oprange[a&obj.AMask] = oprange[b0] -} - -func buildop(ctxt *obj.Link) { - var n int - - for i := 0; i < C_GOK; i++ { - for n = 0; n < C_GOK; n++ { - if cmp(n, i) { - xcmp[i][n] = true - } - } - } - for n = 0; optab[n].as != obj.AXXX; n++ { - if optab[n].flag&LPCREL != 0 { - if ctxt.Flag_shared { - optab[n].size += int8(optab[n].pcrelsiz) - } else { - optab[n].flag &^= LPCREL - } - } - } - - sort.Sort(ocmp(optab[:n])) - for i := 0; i < n; i++ { - r := optab[i].as - r0 := r & obj.AMask - start := i - for optab[i].as == r { - i++ - } - oprange[r0] = optab[start:i] - i-- - - switch r { - default: - ctxt.Diag("unknown op in build: %v", r) - log.Fatalf("bad code") - - case AADD: - opset(AAND, r0) - opset(AEOR, r0) - opset(ASUB, r0) - opset(ARSB, r0) - opset(AADC, r0) - opset(ASBC, r0) - opset(ARSC, r0) - opset(AORR, r0) - opset(ABIC, r0) - - case ACMP: - opset(ATEQ, r0) - opset(ACMN, r0) - - case AMVN: - break - - case ABEQ: - opset(ABNE, r0) - opset(ABCS, r0) - opset(ABHS, r0) - opset(ABCC, r0) - opset(ABLO, r0) - opset(ABMI, r0) - opset(ABPL, r0) - opset(ABVS, r0) - opset(ABVC, r0) - opset(ABHI, r0) - opset(ABLS, r0) - opset(ABGE, r0) - opset(ABLT, r0) - opset(ABGT, r0) - opset(ABLE, r0) - - case ASLL: - opset(ASRL, r0) - opset(ASRA, r0) - - case AMUL: - opset(AMULU, r0) - - case ADIV: - opset(AMOD, r0) - opset(AMODU, r0) - opset(ADIVU, r0) - - case AMOVW, - AMOVB, - AMOVBS, - AMOVBU, - AMOVH, - AMOVHS, - AMOVHU: - break - - case ASWPW: - opset(ASWPBU, r0) - - case AB, - ABL, - ABX, - ABXRET, - obj.ADUFFZERO, - obj.ADUFFCOPY, - ASWI, - AWORD, - AMOVM, - ARFE, - obj.ATEXT, - obj.AUSEFIELD, - obj.ATYPE: - break - - case AADDF: - opset(AADDD, r0) - opset(ASUBF, r0) - opset(ASUBD, r0) - opset(AMULF, r0) - opset(AMULD, r0) - opset(ADIVF, r0) - opset(ADIVD, r0) - opset(ASQRTF, r0) - opset(ASQRTD, r0) - opset(AMOVFD, r0) - opset(AMOVDF, r0) - opset(AABSF, r0) - opset(AABSD, r0) - opset(ANEGF, r0) - opset(ANEGD, r0) - - case ACMPF: - opset(ACMPD, r0) - - case AMOVF: - opset(AMOVD, r0) - - case AMOVFW: - opset(AMOVDW, r0) - - case AMOVWF: - opset(AMOVWD, r0) - - case AMULL: - opset(AMULAL, r0) - opset(AMULLU, r0) - opset(AMULALU, r0) - - case AMULWT: - opset(AMULWB, r0) - - case AMULAWT: - opset(AMULAWB, r0) - - case AMULA, - ALDREX, - ASTREX, - ALDREXD, - ASTREXD, - ATST, - APLD, - obj.AUNDEF, - ACLZ, - obj.AFUNCDATA, - obj.APCDATA, - obj.ANOP, - ADATABUNDLE, - ADATABUNDLEEND: - break - } - } -} - -func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { - ctxt.Printp = p - o1 := uint32(0) - o2 := uint32(0) - o3 := uint32(0) - o4 := uint32(0) - o5 := uint32(0) - o6 := uint32(0) - ctxt.Armsize += int32(o.size) - if false { /*debug['P']*/ - fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_) - } - switch o.type_ { - default: - ctxt.Diag("unknown asm %d", o.type_) - prasm(p) - - case 0: /* pseudo ops */ - if false { /*debug['G']*/ - fmt.Printf("%x: %s: arm\n", uint32(p.Pc), p.From.Sym.Name) - } - - case 1: /* op R,[R],R */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - r := int(p.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = 0 - } - if p.As == AMOVB || p.As == AMOVH || p.As == AMOVW || p.As == AMVN { - r = 0 - } else if r == 0 { - r = rt - } - o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - - case 2: /* movbu $I,[R],R */ - aclass(ctxt, &p.From) - - o1 = oprrr(ctxt, p.As, int(p.Scond)) - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - rt := int(p.To.Reg) - r := int(p.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = 0 - } - if p.As == AMOVW || p.As == AMVN { - r = 0 - } else if r == 0 { - r = rt - } - o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - - case 3: /* add R<<[IR],[R],R */ - o1 = mov(ctxt, p) - - case 4: /* MOVW $off(R), R -> add $off,[R],R */ - aclass(ctxt, &p.From) - if ctxt.Instoffset < 0 { - o1 = oprrr(ctxt, ASUB, int(p.Scond)) - o1 |= uint32(immrot(uint32(-ctxt.Instoffset))) - } else { - o1 = oprrr(ctxt, AADD, int(p.Scond)) - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 |= (uint32(r) & 15) << 16 - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 5: /* bra s */ - o1 = opbra(ctxt, p, p.As, int(p.Scond)) - - v := int32(-8) - if p.To.Sym != nil { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - v += int32(p.To.Offset) - rel.Add = int64(o1) | (int64(v)>>2)&0xffffff - rel.Type = obj.R_CALLARM - break - } - - if p.Pcond != nil { - v = int32((p.Pcond.Pc - ctxt.Pc) - 8) - } - o1 |= (uint32(v) >> 2) & 0xffffff - - case 6: /* b ,O(R) -> add $O,R,PC */ - aclass(ctxt, &p.To) - - o1 = oprrr(ctxt, AADD, int(p.Scond)) - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - o1 |= (uint32(p.To.Reg) & 15) << 16 - o1 |= (REGPC & 15) << 12 - - case 7: /* bl (R) -> blx R */ - aclass(ctxt, &p.To) - - if ctxt.Instoffset != 0 { - ctxt.Diag("%v: doesn't support BL offset(REG) with non-zero offset %d", p, ctxt.Instoffset) - } - o1 = oprrr(ctxt, ABL, int(p.Scond)) - o1 |= (uint32(p.To.Reg) & 15) << 0 - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 0 - rel.Type = obj.R_CALLIND - - case 8: /* sll $c,[R],R -> mov (R<<$c),R */ - aclass(ctxt, &p.From) - - o1 = oprrr(ctxt, p.As, int(p.Scond)) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 |= (uint32(r) & 15) << 0 - o1 |= uint32((ctxt.Instoffset & 31) << 7) - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 9: /* sll R,[R],R -> mov (R< lr */ - aclass(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = olr(ctxt, int32(ctxt.Instoffset), r, int(p.To.Reg), int(p.Scond)) - if p.As != AMOVW { - o1 |= 1 << 22 - } - - case 30: /* mov/movb/movbu R,L(R) */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o2 = osrr(ctxt, int(p.From.Reg), REGTMP&15, r, int(p.Scond)) - if p.As != AMOVW { - o2 |= 1 << 22 - } - - case 31: /* mov/movbu L(R),R -> lr[b] */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 = olrr(ctxt, REGTMP&15, r, int(p.To.Reg), int(p.Scond)) - if p.As == AMOVBU || p.As == AMOVBS || p.As == AMOVB { - o2 |= 1 << 22 - } - - case 34: /* mov $lacon,R */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - - o2 = oprrr(ctxt, AADD, int(p.Scond)) - o2 |= REGTMP & 15 - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 |= (uint32(r) & 15) << 16 - if p.To.Type != obj.TYPE_NONE { - o2 |= (uint32(p.To.Reg) & 15) << 12 - } - - case 35: /* mov PSR,R */ - o1 = 2<<23 | 0xf<<16 | 0<<0 - - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - o1 |= (uint32(p.From.Reg) & 1) << 22 - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 36: /* mov R,PSR */ - o1 = 2<<23 | 0x29f<<12 | 0<<4 - - if p.Scond&C_FBIT != 0 { - o1 ^= 0x010 << 12 - } - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - o1 |= (uint32(p.To.Reg) & 1) << 22 - o1 |= (uint32(p.From.Reg) & 15) << 0 - - case 37: /* mov $con,PSR */ - aclass(ctxt, &p.From) - - o1 = 2<<23 | 0x29f<<12 | 0<<4 - if p.Scond&C_FBIT != 0 { - o1 ^= 0x010 << 12 - } - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - o1 |= (uint32(p.To.Reg) & 1) << 22 - o1 |= (uint32(p.From.Reg) & 15) << 0 - - case 38, 39: - switch o.type_ { - case 38: /* movm $con,oreg -> stm */ - o1 = 0x4 << 25 - - o1 |= uint32(p.From.Offset & 0xffff) - o1 |= (uint32(p.To.Reg) & 15) << 16 - aclass(ctxt, &p.To) - - case 39: /* movm oreg,$con -> ldm */ - o1 = 0x4<<25 | 1<<20 - - o1 |= uint32(p.To.Offset & 0xffff) - o1 |= (uint32(p.From.Reg) & 15) << 16 - aclass(ctxt, &p.From) - } - - if ctxt.Instoffset != 0 { - ctxt.Diag("offset must be zero in MOVM; %v", p) - } - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - if p.Scond&C_PBIT != 0 { - o1 |= 1 << 24 - } - if p.Scond&C_UBIT != 0 { - o1 |= 1 << 23 - } - if p.Scond&C_SBIT != 0 { - o1 |= 1 << 22 - } - if p.Scond&C_WBIT != 0 { - o1 |= 1 << 21 - } - - case 40: /* swp oreg,reg,reg */ - aclass(ctxt, &p.From) - - if ctxt.Instoffset != 0 { - ctxt.Diag("offset must be zero in SWP") - } - o1 = 0x2<<23 | 0x9<<4 - if p.As != ASWPW { - o1 |= 1 << 22 - } - o1 |= (uint32(p.From.Reg) & 15) << 16 - o1 |= (uint32(p.Reg) & 15) << 0 - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 41: /* rfe -> movm.s.w.u 0(r13),[r15] */ - o1 = 0xe8fd8000 - - case 50: /* floating point store */ - v := regoff(ctxt, &p.To) - - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o1 = ofsr(ctxt, p.As, int(p.From.Reg), v, r, int(p.Scond), p) - - case 51: /* floating point load */ - v := regoff(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = ofsr(ctxt, p.As, int(p.To.Reg), v, r, int(p.Scond), p) | 1<<20 - - case 52: /* floating point store, int32 offset UGLY */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o2 = oprrr(ctxt, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0 - o3 = ofsr(ctxt, p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond), p) - - case 53: /* floating point load, int32 offset UGLY */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 = oprrr(ctxt, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0 - o3 = ofsr(ctxt, p.As, int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20 - - case 54: /* floating point arith */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - r := int(p.Reg) - if r == 0 { - r = rt - if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD || p.As == ANEGF || p.As == ANEGD { - r = 0 - } - } - - o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - - case 56: /* move to FP[CS]R */ - o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xe<<24 | 1<<8 | 1<<4 - - o1 |= ((uint32(p.To.Reg)&1)+1)<<21 | (uint32(p.From.Reg)&15)<<12 - - case 57: /* move from FP[CS]R */ - o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xe<<24 | 1<<8 | 1<<4 - - o1 |= ((uint32(p.From.Reg)&1)+1)<<21 | (uint32(p.To.Reg)&15)<<12 | 1<<20 - - case 58: /* movbu R,R */ - o1 = oprrr(ctxt, AAND, int(p.Scond)) - - o1 |= uint32(immrot(0xff)) - rt := int(p.To.Reg) - r := int(p.From.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = 0 - } - if r == 0 { - r = rt - } - o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - - case 59: /* movw/bu R< ldr indexed */ - if p.From.Reg == 0 { - if p.As != AMOVW { - ctxt.Diag("byte MOV from shifter operand") - } - o1 = mov(ctxt, p) - break - } - - if p.From.Offset&(1<<4) != 0 { - ctxt.Diag("bad shift in LDR") - } - o1 = olrr(ctxt, int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond)) - if p.As == AMOVBU { - o1 |= 1 << 22 - } - - case 60: /* movb R(R),R -> ldrsb indexed */ - if p.From.Reg == 0 { - ctxt.Diag("byte MOV from shifter operand") - o1 = mov(ctxt, p) - break - } - - if p.From.Offset&(^0xf) != 0 { - ctxt.Diag("bad shift in LDRSB") - } - o1 = olhrr(ctxt, int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond)) - o1 ^= 1<<5 | 1<<6 - - case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */ - if p.To.Reg == 0 { - ctxt.Diag("MOV to shifter operand") - } - o1 = osrr(ctxt, int(p.From.Reg), int(p.To.Offset), int(p.To.Reg), int(p.Scond)) - if p.As == AMOVB || p.As == AMOVBS || p.As == AMOVBU { - o1 |= 1 << 22 - } - - /* reloc ops */ - case 64: /* mov/movb/movbu R,addr */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - o2 = osr(ctxt, p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond)) - if o.flag&LPCREL != 0 { - o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 - } - - case 65: /* mov/movbu addr,R */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - o2 = olr(ctxt, 0, REGTMP, int(p.To.Reg), int(p.Scond)) - if p.As == AMOVBU || p.As == AMOVBS || p.As == AMOVB { - o2 |= 1 << 22 - } - if o.flag&LPCREL != 0 { - o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 - } - - case 101: /* movw tlsvar,R, local exec*/ - if p.Scond&C_SCOND != C_SCOND_NONE { - ctxt.Diag("conditional tls") - } - o1 = omvl(ctxt, p, &p.From, int(p.To.Reg)) - - case 102: /* movw tlsvar,R, initial exec*/ - if p.Scond&C_SCOND != C_SCOND_NONE { - ctxt.Diag("conditional tls") - } - o1 = omvl(ctxt, p, &p.From, int(p.To.Reg)) - o2 = olrr(ctxt, int(p.To.Reg)&15, (REGPC & 15), int(p.To.Reg), int(p.Scond)) - - case 103: /* word tlsvar, local exec */ - if p.To.Sym == nil { - ctxt.Diag("nil sym in tls %v", p) - } - if p.To.Offset != 0 { - ctxt.Diag("offset against tls var in %v", p) - } - // This case happens with words generated in the PC stream as part of - // the literal pool. - rel := obj.Addrel(ctxt.Cursym) - - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Type = obj.R_TLS_LE - o1 = 0 - - case 104: /* word tlsvar, initial exec */ - if p.To.Sym == nil { - ctxt.Diag("nil sym in tls %v", p) - } - if p.To.Offset != 0 { - ctxt.Diag("offset against tls var in %v", p) - } - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Type = obj.R_TLS_IE - rel.Add = ctxt.Pc - p.Rel.Pc - 8 - int64(rel.Siz) - - case 68: /* floating point store -> ADDR */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - o2 = ofsr(ctxt, p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond), p) - if o.flag&LPCREL != 0 { - o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 - } - - case 69: /* floating point load <- ADDR */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - o2 = ofsr(ctxt, p.As, int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20 - if o.flag&LPCREL != 0 { - o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 - } - - /* ArmV4 ops: */ - case 70: /* movh/movhu R,O(R) -> strh */ - aclass(ctxt, &p.To) - - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o1 = oshr(ctxt, int(p.From.Reg), int32(ctxt.Instoffset), r, int(p.Scond)) - - case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */ - aclass(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = olhr(ctxt, int32(ctxt.Instoffset), r, int(p.To.Reg), int(p.Scond)) - if p.As == AMOVB || p.As == AMOVBS { - o1 ^= 1<<5 | 1<<6 - } else if p.As == AMOVH || p.As == AMOVHS { - o1 ^= (1 << 6) - } - - case 72: /* movh/movhu R,L(R) -> strh */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o2 = oshrr(ctxt, int(p.From.Reg), REGTMP&15, r, int(p.Scond)) - - case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 = olhrr(ctxt, REGTMP&15, r, int(p.To.Reg), int(p.Scond)) - if p.As == AMOVB || p.As == AMOVBS { - o2 ^= 1<<5 | 1<<6 - } else if p.As == AMOVH || p.As == AMOVHS { - o2 ^= (1 << 6) - } - - case 74: /* bx $I */ - ctxt.Diag("ABX $I") - - case 75: /* bx O(R) */ - aclass(ctxt, &p.To) - - if ctxt.Instoffset != 0 { - ctxt.Diag("non-zero offset in ABX") - } - - /* - o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR - o2 = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0); // BX R - */ - // p->to.reg may be REGLINK - o1 = oprrr(ctxt, AADD, int(p.Scond)) - - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - o1 |= (uint32(p.To.Reg) & 15) << 16 - o1 |= (REGTMP & 15) << 12 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(immrot(0)) | (REGPC&15)<<16 | (REGLINK&15)<<12 // mov PC, LR - o3 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x12fff<<8 | 1<<4 | REGTMP&15 // BX Rtmp - - case 76: /* bx O(R) when returning from fn*/ - ctxt.Diag("ABXRET") - - case 77: /* ldrex oreg,reg */ - aclass(ctxt, &p.From) - - if ctxt.Instoffset != 0 { - ctxt.Diag("offset must be zero in LDREX") - } - o1 = 0x19<<20 | 0xf9f - o1 |= (uint32(p.From.Reg) & 15) << 16 - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 78: /* strex reg,oreg,reg */ - aclass(ctxt, &p.From) - - if ctxt.Instoffset != 0 { - ctxt.Diag("offset must be zero in STREX") - } - o1 = 0x18<<20 | 0xf90 - o1 |= (uint32(p.From.Reg) & 15) << 16 - o1 |= (uint32(p.Reg) & 15) << 0 - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 80: /* fmov zfcon,freg */ - if p.As == AMOVD { - o1 = 0xeeb00b00 // VMOV imm 64 - o2 = oprrr(ctxt, ASUBD, int(p.Scond)) - } else { - o1 = 0x0eb00a00 // VMOV imm 32 - o2 = oprrr(ctxt, ASUBF, int(p.Scond)) - } - - v := int32(0x70) // 1.0 - r := (int(p.To.Reg) & 15) << 0 - - // movf $1.0, r - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - o1 |= (uint32(r) & 15) << 12 - o1 |= (uint32(v) & 0xf) << 0 - o1 |= (uint32(v) & 0xf0) << 12 - - // subf r,r,r - o2 |= (uint32(r)&15)<<0 | (uint32(r)&15)<<16 | (uint32(r)&15)<<12 - - case 81: /* fmov sfcon,freg */ - o1 = 0x0eb00a00 // VMOV imm 32 - if p.As == AMOVD { - o1 = 0xeeb00b00 // VMOV imm 64 - } - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - o1 |= (uint32(p.To.Reg) & 15) << 12 - v := int32(chipfloat5(ctxt, p.From.Val.(float64))) - o1 |= (uint32(v) & 0xf) << 0 - o1 |= (uint32(v) & 0xf0) << 12 - - case 82: /* fcmp freg,freg, */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.Reg)&15)<<12 | (uint32(p.From.Reg)&15)<<0 - o2 = 0x0ef1fa10 // VMRS R15 - o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 83: /* fcmp freg,, */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.From.Reg)&15)<<12 | 1<<16 - o2 = 0x0ef1fa10 // VMRS R15 - o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 84: /* movfw freg,freg - truncate float-to-fix */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 0 - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 85: /* movwf freg,freg - fix-to-float */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 0 - o1 |= (uint32(p.To.Reg) & 15) << 12 - - // macro for movfw freg,FTMP; movw FTMP,reg - case 86: /* movfw freg,reg - truncate float-to-fix */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 0 - o1 |= (FREGTMP & 15) << 12 - o2 = oprrr(ctxt, -AMOVFW, int(p.Scond)) - o2 |= (FREGTMP & 15) << 16 - o2 |= (uint32(p.To.Reg) & 15) << 12 - - // macro for movw reg,FTMP; movwf FTMP,freg - case 87: /* movwf reg,freg - fix-to-float */ - o1 = oprrr(ctxt, -AMOVWF, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 12 - o1 |= (FREGTMP & 15) << 16 - o2 = oprrr(ctxt, p.As, int(p.Scond)) - o2 |= (FREGTMP & 15) << 0 - o2 |= (uint32(p.To.Reg) & 15) << 12 - - case 88: /* movw reg,freg */ - o1 = oprrr(ctxt, -AMOVWF, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 12 - o1 |= (uint32(p.To.Reg) & 15) << 16 - - case 89: /* movw freg,reg */ - o1 = oprrr(ctxt, -AMOVFW, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 16 - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 90: /* tst reg */ - o1 = oprrr(ctxt, -ACMP, int(p.Scond)) - - o1 |= (uint32(p.From.Reg) & 15) << 16 - - case 91: /* ldrexd oreg,reg */ - aclass(ctxt, &p.From) - - if ctxt.Instoffset != 0 { - ctxt.Diag("offset must be zero in LDREX") - } - o1 = 0x1b<<20 | 0xf9f - o1 |= (uint32(p.From.Reg) & 15) << 16 - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 92: /* strexd reg,oreg,reg */ - aclass(ctxt, &p.From) - - if ctxt.Instoffset != 0 { - ctxt.Diag("offset must be zero in STREX") - } - o1 = 0x1a<<20 | 0xf90 - o1 |= (uint32(p.From.Reg) & 15) << 16 - o1 |= (uint32(p.Reg) & 15) << 0 - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - - case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - o2 = olhr(ctxt, 0, REGTMP, int(p.To.Reg), int(p.Scond)) - if p.As == AMOVB || p.As == AMOVBS { - o2 ^= 1<<5 | 1<<6 - } else if p.As == AMOVH || p.As == AMOVHS { - o2 ^= (1 << 6) - } - if o.flag&LPCREL != 0 { - o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 - } - - case 94: /* movh/movhu R,addr -> strh */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - o2 = oshr(ctxt, int(p.From.Reg), 0, REGTMP, int(p.Scond)) - if o.flag&LPCREL != 0 { - o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 - } - - case 95: /* PLD off(reg) */ - o1 = 0xf5d0f000 - - o1 |= (uint32(p.From.Reg) & 15) << 16 - if p.From.Offset < 0 { - o1 &^= (1 << 23) - o1 |= uint32((-p.From.Offset) & 0xfff) - } else { - o1 |= uint32(p.From.Offset & 0xfff) - } - - // This is supposed to be something that stops execution. - // It's not supposed to be reached, ever, but if it is, we'd - // like to be able to tell how we got there. Assemble as - // 0xf7fabcfd which is guaranteed to raise undefined instruction - // exception. - case 96: /* UNDEF */ - o1 = 0xf7fabcfd - - case 97: /* CLZ Rm, Rd */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= (uint32(p.From.Reg) & 15) << 0 - - case 98: /* MULW{T,B} Rs, Rm, Rd */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.To.Reg) & 15) << 16 - o1 |= (uint32(p.From.Reg) & 15) << 8 - o1 |= (uint32(p.Reg) & 15) << 0 - - case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - o1 |= (uint32(p.To.Reg) & 15) << 12 - o1 |= (uint32(p.From.Reg) & 15) << 8 - o1 |= (uint32(p.Reg) & 15) << 0 - o1 |= uint32((p.To.Offset & 15) << 16) - - // DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle; - // DATABUNDLEEND: zero width alignment marker - case 100: - if p.As == ADATABUNDLE { - o1 = 0xe125be70 - } - } - - out[0] = o1 - out[1] = o2 - out[2] = o3 - out[3] = o4 - out[4] = o5 - out[5] = o6 - return -} - -func mov(ctxt *obj.Link, p *obj.Prog) uint32 { - aclass(ctxt, &p.From) - o1 := oprrr(ctxt, p.As, int(p.Scond)) - o1 |= uint32(p.From.Offset) - rt := int(p.To.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = 0 - } - r := int(p.Reg) - if p.As == AMOVW || p.As == AMVN { - r = 0 - } else if r == 0 { - r = rt - } - o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - return o1 -} - -func oprrr(ctxt *obj.Link, a obj.As, sc int) uint32 { - o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 - if sc&C_SBIT != 0 { - o |= 1 << 20 - } - if sc&(C_PBIT|C_WBIT) != 0 { - ctxt.Diag(".nil/.W on dp instruction") - } - switch a { - case AMULU, AMUL: - return o | 0x0<<21 | 0x9<<4 - case AMULA: - return o | 0x1<<21 | 0x9<<4 - case AMULLU: - return o | 0x4<<21 | 0x9<<4 - case AMULL: - return o | 0x6<<21 | 0x9<<4 - case AMULALU: - return o | 0x5<<21 | 0x9<<4 - case AMULAL: - return o | 0x7<<21 | 0x9<<4 - case AAND: - return o | 0x0<<21 - case AEOR: - return o | 0x1<<21 - case ASUB: - return o | 0x2<<21 - case ARSB: - return o | 0x3<<21 - case AADD: - return o | 0x4<<21 - case AADC: - return o | 0x5<<21 - case ASBC: - return o | 0x6<<21 - case ARSC: - return o | 0x7<<21 - case ATST: - return o | 0x8<<21 | 1<<20 - case ATEQ: - return o | 0x9<<21 | 1<<20 - case ACMP: - return o | 0xa<<21 | 1<<20 - case ACMN: - return o | 0xb<<21 | 1<<20 - case AORR: - return o | 0xc<<21 - - case AMOVB, AMOVH, AMOVW: - return o | 0xd<<21 - case ABIC: - return o | 0xe<<21 - case AMVN: - return o | 0xf<<21 - case ASLL: - return o | 0xd<<21 | 0<<5 - case ASRL: - return o | 0xd<<21 | 1<<5 - case ASRA: - return o | 0xd<<21 | 2<<5 - case ASWI: - return o | 0xf<<24 - - case AADDD: - return o | 0xe<<24 | 0x3<<20 | 0xb<<8 | 0<<4 - case AADDF: - return o | 0xe<<24 | 0x3<<20 | 0xa<<8 | 0<<4 - case ASUBD: - return o | 0xe<<24 | 0x3<<20 | 0xb<<8 | 4<<4 - case ASUBF: - return o | 0xe<<24 | 0x3<<20 | 0xa<<8 | 4<<4 - case AMULD: - return o | 0xe<<24 | 0x2<<20 | 0xb<<8 | 0<<4 - case AMULF: - return o | 0xe<<24 | 0x2<<20 | 0xa<<8 | 0<<4 - case ADIVD: - return o | 0xe<<24 | 0x8<<20 | 0xb<<8 | 0<<4 - case ADIVF: - return o | 0xe<<24 | 0x8<<20 | 0xa<<8 | 0<<4 - case ASQRTD: - return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xb<<8 | 0xc<<4 - case ASQRTF: - return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xa<<8 | 0xc<<4 - case AABSD: - return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xb<<8 | 0xc<<4 - case AABSF: - return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xa<<8 | 0xc<<4 - case ANEGD: - return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xb<<8 | 0x4<<4 - case ANEGF: - return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xa<<8 | 0x4<<4 - case ACMPD: - return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xb<<8 | 0xc<<4 - case ACMPF: - return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xa<<8 | 0xc<<4 - - case AMOVF: - return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xa<<8 | 4<<4 - case AMOVD: - return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xb<<8 | 4<<4 - - case AMOVDF: - return o | 0xe<<24 | 0xb<<20 | 7<<16 | 0xa<<8 | 0xc<<4 | 1<<8 // dtof - case AMOVFD: - return o | 0xe<<24 | 0xb<<20 | 7<<16 | 0xa<<8 | 0xc<<4 | 0<<8 // dtof - - case AMOVWF: - if sc&C_UBIT == 0 { - o |= 1 << 7 /* signed */ - } - return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 0<<18 | 0<<8 // toint, double - - case AMOVWD: - if sc&C_UBIT == 0 { - o |= 1 << 7 /* signed */ - } - return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 0<<18 | 1<<8 // toint, double - - case AMOVFW: - if sc&C_UBIT == 0 { - o |= 1 << 16 /* signed */ - } - return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 0<<8 | 1<<7 // toint, double, trunc - - case AMOVDW: - if sc&C_UBIT == 0 { - o |= 1 << 16 /* signed */ - } - return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 1<<8 | 1<<7 // toint, double, trunc - - case -AMOVWF: // copy WtoF - return o | 0xe<<24 | 0x0<<20 | 0xb<<8 | 1<<4 - - case -AMOVFW: // copy FtoW - return o | 0xe<<24 | 0x1<<20 | 0xb<<8 | 1<<4 - - case -ACMP: // cmp imm - return o | 0x3<<24 | 0x5<<20 - - // CLZ doesn't support .nil - case ACLZ: - return o&(0xf<<28) | 0x16f<<16 | 0xf1<<4 - - case AMULWT: - return o&(0xf<<28) | 0x12<<20 | 0xe<<4 - - case AMULWB: - return o&(0xf<<28) | 0x12<<20 | 0xa<<4 - - case AMULAWT: - return o&(0xf<<28) | 0x12<<20 | 0xc<<4 - - case AMULAWB: - return o&(0xf<<28) | 0x12<<20 | 0x8<<4 - - case ABL: // BLX REG - return o&(0xf<<28) | 0x12fff3<<4 - } - - ctxt.Diag("bad rrr %d", a) - prasm(ctxt.Curp) - return 0 -} - -func opbra(ctxt *obj.Link, p *obj.Prog, a obj.As, sc int) uint32 { - if sc&(C_SBIT|C_PBIT|C_WBIT) != 0 { - ctxt.Diag("%v: .nil/.nil/.W on bra instruction", p) - } - sc &= C_SCOND - sc ^= C_SCOND_XOR - if a == ABL || a == obj.ADUFFZERO || a == obj.ADUFFCOPY { - return uint32(sc)<<28 | 0x5<<25 | 0x1<<24 - } - if sc != 0xe { - ctxt.Diag("%v: .COND on bcond instruction", p) - } - switch a { - case ABEQ: - return 0x0<<28 | 0x5<<25 - case ABNE: - return 0x1<<28 | 0x5<<25 - case ABCS: - return 0x2<<28 | 0x5<<25 - case ABHS: - return 0x2<<28 | 0x5<<25 - case ABCC: - return 0x3<<28 | 0x5<<25 - case ABLO: - return 0x3<<28 | 0x5<<25 - case ABMI: - return 0x4<<28 | 0x5<<25 - case ABPL: - return 0x5<<28 | 0x5<<25 - case ABVS: - return 0x6<<28 | 0x5<<25 - case ABVC: - return 0x7<<28 | 0x5<<25 - case ABHI: - return 0x8<<28 | 0x5<<25 - case ABLS: - return 0x9<<28 | 0x5<<25 - case ABGE: - return 0xa<<28 | 0x5<<25 - case ABLT: - return 0xb<<28 | 0x5<<25 - case ABGT: - return 0xc<<28 | 0x5<<25 - case ABLE: - return 0xd<<28 | 0x5<<25 - case AB: - return 0xe<<28 | 0x5<<25 - } - - ctxt.Diag("bad bra %v", a) - prasm(ctxt.Curp) - return 0 -} - -func olr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 { - if sc&C_SBIT != 0 { - ctxt.Diag(".nil on LDR/STR instruction") - } - o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 - if sc&C_PBIT == 0 { - o |= 1 << 24 - } - if sc&C_UBIT == 0 { - o |= 1 << 23 - } - if sc&C_WBIT != 0 { - o |= 1 << 21 - } - o |= 1<<26 | 1<<20 - if v < 0 { - if sc&C_UBIT != 0 { - ctxt.Diag(".U on neg offset") - } - v = -v - o ^= 1 << 23 - } - - if v >= 1<<12 || v < 0 { - ctxt.Diag("literal span too large: %d (R%d)\n%v", v, b, ctxt.Printp) - } - o |= uint32(v) - o |= (uint32(b) & 15) << 16 - o |= (uint32(r) & 15) << 12 - return o -} - -func olhr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 { - if sc&C_SBIT != 0 { - ctxt.Diag(".nil on LDRH/STRH instruction") - } - o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 - if sc&C_PBIT == 0 { - o |= 1 << 24 - } - if sc&C_WBIT != 0 { - o |= 1 << 21 - } - o |= 1<<23 | 1<<20 | 0xb<<4 - if v < 0 { - v = -v - o ^= 1 << 23 - } - - if v >= 1<<8 || v < 0 { - ctxt.Diag("literal span too large: %d (R%d)\n%v", v, b, ctxt.Printp) - } - o |= uint32(v)&0xf | (uint32(v)>>4)<<8 | 1<<22 - o |= (uint32(b) & 15) << 16 - o |= (uint32(r) & 15) << 12 - return o -} - -func osr(ctxt *obj.Link, a obj.As, r int, v int32, b int, sc int) uint32 { - o := olr(ctxt, v, b, r, sc) ^ (1 << 20) - if a != AMOVW { - o |= 1 << 22 - } - return o -} - -func oshr(ctxt *obj.Link, r int, v int32, b int, sc int) uint32 { - o := olhr(ctxt, v, b, r, sc) ^ (1 << 20) - return o -} - -func osrr(ctxt *obj.Link, r int, i int, b int, sc int) uint32 { - return olr(ctxt, int32(i), b, r, sc) ^ (1<<25 | 1<<20) -} - -func oshrr(ctxt *obj.Link, r int, i int, b int, sc int) uint32 { - return olhr(ctxt, int32(i), b, r, sc) ^ (1<<22 | 1<<20) -} - -func olrr(ctxt *obj.Link, i int, b int, r int, sc int) uint32 { - return olr(ctxt, int32(i), b, r, sc) ^ (1 << 25) -} - -func olhrr(ctxt *obj.Link, i int, b int, r int, sc int) uint32 { - return olhr(ctxt, int32(i), b, r, sc) ^ (1 << 22) -} - -func ofsr(ctxt *obj.Link, a obj.As, r int, v int32, b int, sc int, p *obj.Prog) uint32 { - if sc&C_SBIT != 0 { - ctxt.Diag(".nil on FLDR/FSTR instruction: %v", p) - } - o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 - if sc&C_PBIT == 0 { - o |= 1 << 24 - } - if sc&C_WBIT != 0 { - o |= 1 << 21 - } - o |= 6<<25 | 1<<24 | 1<<23 | 10<<8 - if v < 0 { - v = -v - o ^= 1 << 23 - } - - if v&3 != 0 { - ctxt.Diag("odd offset for floating point op: %d\n%v", v, p) - } else if v >= 1<<10 || v < 0 { - ctxt.Diag("literal span too large: %d\n%v", v, p) - } - o |= (uint32(v) >> 2) & 0xFF - o |= (uint32(b) & 15) << 16 - o |= (uint32(r) & 15) << 12 - - switch a { - default: - ctxt.Diag("bad fst %v", a) - fallthrough - - case AMOVD: - o |= 1 << 8 - fallthrough - - case AMOVF: - break - } - - return o -} - -func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 { - var o1 uint32 - if p.Pcond == nil { - aclass(ctxt, a) - v := immrot(^uint32(ctxt.Instoffset)) - if v == 0 { - ctxt.Diag("missing literal") - prasm(p) - return 0 - } - - o1 = oprrr(ctxt, AMVN, int(p.Scond)&C_SCOND) - o1 |= uint32(v) - o1 |= (uint32(dr) & 15) << 12 - } else { - v := int32(p.Pcond.Pc - p.Pc - 8) - o1 = olr(ctxt, v, REGPC, dr, int(p.Scond)&C_SCOND) - } - - return o1 -} - -func chipzero5(ctxt *obj.Link, e float64) int { - // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions. - if obj.GOARM < 7 || e != 0 { - return -1 - } - return 0 -} - -func chipfloat5(ctxt *obj.Link, e float64) int { - // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions. - if obj.GOARM < 7 { - return -1 - } - - ei := math.Float64bits(e) - l := uint32(ei) - h := uint32(ei >> 32) - - if l != 0 || h&0xffff != 0 { - return -1 - } - h1 := h & 0x7fc00000 - if h1 != 0x40000000 && h1 != 0x3fc00000 { - return -1 - } - n := 0 - - // sign bit (a) - if h&0x80000000 != 0 { - n |= 1 << 7 - } - - // exp sign bit (b) - if h1 == 0x3fc00000 { - n |= 1 << 6 - } - - // rest of exp and mantissa (cd-efgh) - n |= int((h >> 16) & 0x3f) - - //print("match %.8lux %.8lux %d\n", l, h, n); - return n -} - -func nocache(p *obj.Prog) { - p.Optab = 0 - p.From.Class = 0 - if p.From3 != nil { - p.From3.Class = 0 - } - p.To.Class = 0 -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/list5.go b/vendor/github.com/google/gops/internal/obj/arm/list5.go deleted file mode 100644 index f6c50168..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm/list5.go +++ /dev/null @@ -1,84 +0,0 @@ -// Inferno utils/5c/list.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/list.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm - -import ( - "fmt" - - "github.com/google/gops/internal/obj" -) - -func init() { - obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv) - obj.RegisterOpcode(obj.ABaseARM, Anames) -} - -func Rconv(r int) string { - if r == 0 { - return "NONE" - } - if r == REGG { - // Special case. - return "g" - } - if REG_R0 <= r && r <= REG_R15 { - return fmt.Sprintf("R%d", r-REG_R0) - } - if REG_F0 <= r && r <= REG_F15 { - return fmt.Sprintf("F%d", r-REG_F0) - } - - switch r { - case REG_FPSR: - return "FPSR" - - case REG_FPCR: - return "FPCR" - - case REG_CPSR: - return "CPSR" - - case REG_SPSR: - return "SPSR" - } - - return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM) -} - -func DRconv(a int) string { - s := "C_??" - if a >= C_NONE && a <= C_NCLASS { - s = cnames5[a] - } - var fp string - fp += s - return fp -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/obj5.go b/vendor/github.com/google/gops/internal/obj/arm/obj5.go deleted file mode 100644 index 2c4e39b7..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm/obj5.go +++ /dev/null @@ -1,1055 +0,0 @@ -// Derived from Inferno utils/5c/swt.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/swt.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm - -import ( - "fmt" - "log" - "math" - - "github.com/google/gops/internal/obj" - "github.com/google/gops/internal/sys" -) - -var progedit_tlsfallback *obj.LSym - -func progedit(ctxt *obj.Link, p *obj.Prog) { - p.From.Class = 0 - p.To.Class = 0 - - // Rewrite B/BL to symbol as TYPE_BRANCH. - switch p.As { - case AB, - ABL, - obj.ADUFFZERO, - obj.ADUFFCOPY: - if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - } - - // Replace TLS register fetches on older ARM processors. - switch p.As { - // Treat MRC 15, 0, , C13, C0, 3 specially. - case AMRC: - if p.To.Offset&0xffff0fff == 0xee1d0f70 { - // Because the instruction might be rewritten to a BL which returns in R0 - // the register must be zero. - if p.To.Offset&0xf000 != 0 { - ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line()) - } - - if obj.GOARM < 7 { - // Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension. - if progedit_tlsfallback == nil { - progedit_tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0) - } - - // MOVW LR, R11 - p.As = AMOVW - - p.From.Type = obj.TYPE_REG - p.From.Reg = REGLINK - p.To.Type = obj.TYPE_REG - p.To.Reg = REGTMP - - // BL runtime.read_tls_fallback(SB) - p = obj.Appendp(ctxt, p) - - p.As = ABL - p.To.Type = obj.TYPE_BRANCH - p.To.Sym = progedit_tlsfallback - p.To.Offset = 0 - - // MOVW R11, LR - p = obj.Appendp(ctxt, p) - - p.As = AMOVW - p.From.Type = obj.TYPE_REG - p.From.Reg = REGTMP - p.To.Type = obj.TYPE_REG - p.To.Reg = REGLINK - break - } - } - - // Otherwise, MRC/MCR instructions need no further treatment. - p.As = AWORD - } - - // Rewrite float constants to values stored in memory. - switch p.As { - case AMOVF: - if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.Val.(float64)) < 0 && (chipzero5(ctxt, p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { - f32 := float32(p.From.Val.(float64)) - i32 := math.Float32bits(f32) - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - case AMOVD: - if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.Val.(float64)) < 0 && (chipzero5(ctxt, p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { - i64 := math.Float64bits(p.From.Val.(float64)) - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - } - - if ctxt.Flag_dynlink { - rewriteToUseGot(ctxt, p) - } -} - -// Rewrite p, if necessary, to access global data via the global offset table. -func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { - if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { - // ADUFFxxx $offset - // becomes - // MOVW runtime.duffxxx@GOT, R9 - // ADD $offset, R9 - // CALL (R9) - var sym *obj.LSym - if p.As == obj.ADUFFZERO { - sym = obj.Linklookup(ctxt, "runtime.duffzero", 0) - } else { - sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0) - } - offset := p.To.Offset - p.As = AMOVW - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - p.From.Sym = sym - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R9 - p.To.Name = obj.NAME_NONE - p.To.Offset = 0 - p.To.Sym = nil - p1 := obj.Appendp(ctxt, p) - p1.As = AADD - p1.From.Type = obj.TYPE_CONST - p1.From.Offset = offset - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REG_R9 - p2 := obj.Appendp(ctxt, p1) - p2.As = obj.ACALL - p2.To.Type = obj.TYPE_MEM - p2.To.Reg = REG_R9 - return - } - - // We only care about global data: NAME_EXTERN means a global - // symbol in the Go sense, and p.Sym.Local is true for a few - // internally defined symbols. - if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - // MOVW $sym, Rx becomes MOVW sym@GOT, Rx - // MOVW $sym+, Rx becomes MOVW sym@GOT, Rx; ADD , Rx - if p.As != AMOVW { - ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p) - } - if p.To.Type != obj.TYPE_REG { - ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p) - } - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - if p.From.Offset != 0 { - q := obj.Appendp(ctxt, p) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = p.From.Offset - q.To = p.To - p.From.Offset = 0 - } - } - if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - var source *obj.Addr - // MOVx sym, Ry becomes MOVW sym@GOT, R9; MOVx (R9), Ry - // MOVx Ry, sym becomes MOVW sym@GOT, R9; MOVx Ry, (R9) - // An addition may be inserted between the two MOVs if there is an offset. - if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) - } - source = &p.From - } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - source = &p.To - } else { - return - } - if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { - return - } - if source.Sym.Type == obj.STLSBSS { - return - } - if source.Type != obj.TYPE_MEM { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - p1 := obj.Appendp(ctxt, p) - p2 := obj.Appendp(ctxt, p1) - - p1.As = AMOVW - p1.From.Type = obj.TYPE_MEM - p1.From.Sym = source.Sym - p1.From.Name = obj.NAME_GOTREF - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REG_R9 - - p2.As = p.As - p2.From = p.From - p2.To = p.To - if p.From.Name == obj.NAME_EXTERN { - p2.From.Reg = REG_R9 - p2.From.Name = obj.NAME_NONE - p2.From.Sym = nil - } else if p.To.Name == obj.NAME_EXTERN { - p2.To.Reg = REG_R9 - p2.To.Name = obj.NAME_NONE - p2.To.Sym = nil - } else { - return - } - obj.Nopout(p) -} - -// Prog.mark -const ( - FOLL = 1 << 0 - LABEL = 1 << 1 - LEAF = 1 << 2 -) - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - autosize := int32(0) - - ctxt.Cursym = cursym - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - softfloat(ctxt, cursym) - - p := cursym.Text - autoffset := int32(p.To.Offset) - if autoffset < 0 { - autoffset = 0 - } - cursym.Locals = autoffset - cursym.Args = p.To.Val.(int32) - - /* - * find leaf subroutines - * strip NOPs - * expand RET - * expand BECOME pseudo - */ - var q1 *obj.Prog - var q *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - switch p.As { - case obj.ATEXT: - p.Mark |= LEAF - - case obj.ARET: - break - - case ADIV, ADIVU, AMOD, AMODU: - q = p - if ctxt.Sym_div == nil { - initdiv(ctxt) - } - cursym.Text.Mark &^= LEAF - continue - - case obj.ANOP: - q1 = p.Link - q.Link = q1 /* q is non-nop */ - if q1 != nil { - q1.Mark |= p.Mark - } - continue - - case ABL, - ABX, - obj.ADUFFZERO, - obj.ADUFFCOPY: - cursym.Text.Mark &^= LEAF - fallthrough - - case AB, - ABEQ, - ABNE, - ABCS, - ABHS, - ABCC, - ABLO, - ABMI, - ABPL, - ABVS, - ABVC, - ABHI, - ABLS, - ABGE, - ABLT, - ABGT, - ABLE: - q1 = p.Pcond - if q1 != nil { - for q1.As == obj.ANOP { - q1 = q1.Link - p.Pcond = q1 - } - } - } - - q = p - } - - var p1 *obj.Prog - var p2 *obj.Prog - var q2 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - o := p.As - switch o { - case obj.ATEXT: - autosize = int32(p.To.Offset + 4) - if autosize <= 4 { - if cursym.Text.Mark&LEAF != 0 { - p.To.Offset = -4 - autosize = 0 - } - } - - if autosize == 0 && cursym.Text.Mark&LEAF == 0 { - if ctxt.Debugvlog != 0 { - ctxt.Logf("save suppressed in: %s\n", cursym.Name) - } - - cursym.Text.Mark |= LEAF - } - - if cursym.Text.Mark&LEAF != 0 { - cursym.Set(obj.AttrLeaf, true) - if autosize == 0 { - break - } - } - - if p.From3.Offset&obj.NOSPLIT == 0 { - p = stacksplit(ctxt, p, autosize) // emit split check - } - - // MOVW.W R14,$-autosize(SP) - p = obj.Appendp(ctxt, p) - - p.As = AMOVW - p.Scond |= C_WBIT - p.From.Type = obj.TYPE_REG - p.From.Reg = REGLINK - p.To.Type = obj.TYPE_MEM - p.To.Offset = int64(-autosize) - p.To.Reg = REGSP - p.Spadj = autosize - - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOVW g_panic(g), R1 - // CMP $0, R1 - // B.EQ end - // MOVW panic_argp(R1), R2 - // ADD $(autosize+4), R13, R3 - // CMP R2, R3 - // B.NE end - // ADD $4, R13, R4 - // MOVW R4, panic_argp(R1) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not an ARM NOP: it encodes to 0 instruction bytes. - - p = obj.Appendp(ctxt, p) - - p.As = AMOVW - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_CONST - p.From.Offset = 0 - p.Reg = REG_R1 - - p = obj.Appendp(ctxt, p) - p.As = ABEQ - p.To.Type = obj.TYPE_BRANCH - p1 = p - - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_R1 - p.From.Offset = 0 // Panic.argp - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autosize) + 4 - p.Reg = REG_R13 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R2 - p.Reg = REG_R3 - - p = obj.Appendp(ctxt, p) - p.As = ABNE - p.To.Type = obj.TYPE_BRANCH - p2 = p - - p = obj.Appendp(ctxt, p) - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = 4 - p.Reg = REG_R13 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R4 - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_R1 - p.To.Offset = 0 // Panic.argp - - p = obj.Appendp(ctxt, p) - - p.As = obj.ANOP - p1.Pcond = p - p2.Pcond = p - } - - case obj.ARET: - nocache(p) - if cursym.Text.Mark&LEAF != 0 { - if autosize == 0 { - p.As = AB - p.From = obj.Addr{} - if p.To.Sym != nil { // retjmp - p.To.Type = obj.TYPE_BRANCH - } else { - p.To.Type = obj.TYPE_MEM - p.To.Offset = 0 - p.To.Reg = REGLINK - } - - break - } - } - - p.As = AMOVW - p.Scond |= C_PBIT - p.From.Type = obj.TYPE_MEM - p.From.Offset = int64(autosize) - p.From.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REGPC - - // If there are instructions following - // this ARET, they come from a branch - // with the same stackframe, so no spadj. - if p.To.Sym != nil { // retjmp - p.To.Reg = REGLINK - q2 = obj.Appendp(ctxt, p) - q2.As = AB - q2.To.Type = obj.TYPE_BRANCH - q2.To.Sym = p.To.Sym - p.To.Sym = nil - p = q2 - } - - case AADD: - if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP { - p.Spadj = int32(-p.From.Offset) - } - - case ASUB: - if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP { - p.Spadj = int32(p.From.Offset) - } - - case ADIV, ADIVU, AMOD, AMODU: - if cursym.Text.From3.Offset&obj.NOSPLIT != 0 { - ctxt.Diag("cannot divide in NOSPLIT function") - } - if ctxt.Debugdivmod != 0 { - break - } - if p.From.Type != obj.TYPE_REG { - break - } - if p.To.Type != obj.TYPE_REG { - break - } - - // Make copy because we overwrite p below. - q1 := *p - if q1.Reg == REGTMP || q1.Reg == 0 && q1.To.Reg == REGTMP { - ctxt.Diag("div already using REGTMP: %v", p) - } - - /* MOV m(g),REGTMP */ - p.As = AMOVW - p.Lineno = q1.Lineno - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 6 * 4 // offset of g.m - p.Reg = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REGTMP - - /* MOV a,m_divmod(REGTMP) */ - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.Lineno = q1.Lineno - p.From.Type = obj.TYPE_REG - p.From.Reg = q1.From.Reg - p.To.Type = obj.TYPE_MEM - p.To.Reg = REGTMP - p.To.Offset = 8 * 4 // offset of m.divmod - - /* MOV b, R8 */ - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.Lineno = q1.Lineno - p.From.Type = obj.TYPE_REG - p.From.Reg = q1.Reg - if q1.Reg == 0 { - p.From.Reg = q1.To.Reg - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R8 - p.To.Offset = 0 - - /* CALL appropriate */ - p = obj.Appendp(ctxt, p) - p.As = ABL - p.Lineno = q1.Lineno - p.To.Type = obj.TYPE_BRANCH - switch o { - case ADIV: - p.To.Sym = ctxt.Sym_div - - case ADIVU: - p.To.Sym = ctxt.Sym_divu - - case AMOD: - p.To.Sym = ctxt.Sym_mod - - case AMODU: - p.To.Sym = ctxt.Sym_modu - } - - /* MOV REGTMP, b */ - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.Lineno = q1.Lineno - p.From.Type = obj.TYPE_REG - p.From.Reg = REGTMP - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = q1.To.Reg - - case AMOVW: - if (p.Scond&C_WBIT != 0) && p.To.Type == obj.TYPE_MEM && p.To.Reg == REGSP { - p.Spadj = int32(-p.To.Offset) - } - if (p.Scond&C_PBIT != 0) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REGSP && p.To.Reg != REGPC { - p.Spadj = int32(-p.From.Offset) - } - if p.From.Type == obj.TYPE_ADDR && p.From.Reg == REGSP && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP { - p.Spadj = int32(-p.From.Offset) - } - } - } -} - -func isfloatreg(a *obj.Addr) bool { - return a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15 -} - -func softfloat(ctxt *obj.Link, cursym *obj.LSym) { - if obj.GOARM > 5 { - return - } - - symsfloat := obj.Linklookup(ctxt, "_sfloat", 0) - - wasfloat := 0 - for p := cursym.Text; p != nil; p = p.Link { - if p.Pcond != nil { - p.Pcond.Mark |= LABEL - } - } - var next *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - switch p.As { - case AMOVW: - if isfloatreg(&p.To) || isfloatreg(&p.From) { - goto soft - } - goto notsoft - - case AMOVWD, - AMOVWF, - AMOVDW, - AMOVFW, - AMOVFD, - AMOVDF, - AMOVF, - AMOVD, - ACMPF, - ACMPD, - AADDF, - AADDD, - ASUBF, - ASUBD, - AMULF, - AMULD, - ADIVF, - ADIVD, - ASQRTF, - ASQRTD, - AABSF, - AABSD, - ANEGF, - ANEGD: - goto soft - - default: - goto notsoft - } - - soft: - if wasfloat == 0 || (p.Mark&LABEL != 0) { - next = ctxt.NewProg() - *next = *p - - // BL _sfloat(SB) - *p = obj.Prog{} - p.Ctxt = ctxt - p.Link = next - p.As = ABL - p.To.Type = obj.TYPE_BRANCH - p.To.Sym = symsfloat - p.Lineno = next.Lineno - - p = next - wasfloat = 1 - } - - continue - - notsoft: - wasfloat = 0 - } -} - -func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { - // MOVW g_stackguard(g), R1 - p = obj.Appendp(ctxt, p) - - p.As = AMOVW - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - - if framesize <= obj.StackSmall { - // small stack: SP < stackguard - // CMP stackguard, SP - p = obj.Appendp(ctxt, p) - - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.Reg = REGSP - } else if framesize <= obj.StackBig { - // large stack: SP-framesize < stackguard-StackSmall - // MOVW $-framesize(SP), R2 - // CMP stackguard, R2 - p = obj.Appendp(ctxt, p) - - p.As = AMOVW - p.From.Type = obj.TYPE_ADDR - p.From.Reg = REGSP - p.From.Offset = int64(-framesize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.Reg = REG_R2 - } else { - // Such a large stack we need to protect against wraparound - // if SP is close to zero. - // SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // CMP $StackPreempt, R1 - // MOVW.NE $StackGuard(SP), R2 - // SUB.NE R1, R2 - // MOVW.NE $(framesize+(StackGuard-StackSmall)), R3 - // CMP.NE R3, R2 - p = obj.Appendp(ctxt, p) - - p.As = ACMP - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) - p.Reg = REG_R1 - - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.From.Type = obj.TYPE_ADDR - p.From.Reg = REGSP - p.From.Offset = obj.StackGuard - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - p.Scond = C_SCOND_NE - - p = obj.Appendp(ctxt, p) - p.As = ASUB - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - p.Scond = C_SCOND_NE - - p = obj.Appendp(ctxt, p) - p.As = AMOVW - p.From.Type = obj.TYPE_ADDR - p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - p.Scond = C_SCOND_NE - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.Reg = REG_R2 - p.Scond = C_SCOND_NE - } - - // BLS call-to-morestack - bls := obj.Appendp(ctxt, p) - bls.As = ABLS - bls.To.Type = obj.TYPE_BRANCH - - var last *obj.Prog - for last = ctxt.Cursym.Text; last.Link != nil; last = last.Link { - } - - // Now we are at the end of the function, but logically - // we are still in function prologue. We need to fix the - // SP data and PCDATA. - spfix := obj.Appendp(ctxt, last) - spfix.As = obj.ANOP - spfix.Spadj = -framesize - - pcdata := obj.Appendp(ctxt, spfix) - pcdata.Lineno = ctxt.Cursym.Text.Lineno - pcdata.Mode = ctxt.Cursym.Text.Mode - pcdata.As = obj.APCDATA - pcdata.From.Type = obj.TYPE_CONST - pcdata.From.Offset = obj.PCDATA_StackMapIndex - pcdata.To.Type = obj.TYPE_CONST - pcdata.To.Offset = -1 // pcdata starts at -1 at function entry - - // MOVW LR, R3 - movw := obj.Appendp(ctxt, pcdata) - movw.As = AMOVW - movw.From.Type = obj.TYPE_REG - movw.From.Reg = REGLINK - movw.To.Type = obj.TYPE_REG - movw.To.Reg = REG_R3 - - bls.Pcond = movw - - // BL runtime.morestack - call := obj.Appendp(ctxt, movw) - call.As = obj.ACALL - call.To.Type = obj.TYPE_BRANCH - morestack := "runtime.morestack" - switch { - case ctxt.Cursym.CFunc(): - morestack = "runtime.morestackc" - case ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0: - morestack = "runtime.morestack_noctxt" - } - call.To.Sym = obj.Linklookup(ctxt, morestack, 0) - - // B start - b := obj.Appendp(ctxt, call) - b.As = obj.AJMP - b.To.Type = obj.TYPE_BRANCH - b.Pcond = ctxt.Cursym.Text.Link - b.Spadj = +framesize - - return bls -} - -func initdiv(ctxt *obj.Link) { - if ctxt.Sym_div != nil { - return - } - ctxt.Sym_div = obj.Linklookup(ctxt, "_div", 0) - ctxt.Sym_divu = obj.Linklookup(ctxt, "_divu", 0) - ctxt.Sym_mod = obj.Linklookup(ctxt, "_mod", 0) - ctxt.Sym_modu = obj.Linklookup(ctxt, "_modu", 0) -} - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func relinv(a obj.As) obj.As { - switch a { - case ABEQ: - return ABNE - case ABNE: - return ABEQ - case ABCS: - return ABCC - case ABHS: - return ABLO - case ABCC: - return ABCS - case ABLO: - return ABHS - case ABMI: - return ABPL - case ABPL: - return ABMI - case ABVS: - return ABVC - case ABVC: - return ABVS - case ABHI: - return ABLS - case ABLS: - return ABHI - case ABGE: - return ABLT - case ABLT: - return ABGE - case ABGT: - return ABLE - case ABLE: - return ABGT - } - - log.Fatalf("unknown relation: %s", Anames[a]) - return 0 -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var r *obj.Prog - var i int - -loop: - if p == nil { - return - } - a := p.As - if a == AB { - q = p.Pcond - if q != nil && q.As != obj.ATEXT { - p.Mark |= FOLL - p = q - if p.Mark&FOLL == 0 { - goto loop - } - } - } - - if p.Mark&FOLL != 0 { - i = 0 - q = p - for ; i < 4; i, q = i+1, q.Link { - if q == *last || q == nil { - break - } - a = q.As - if a == obj.ANOP { - i-- - continue - } - - if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF { - goto copy - } - if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { - continue - } - if a != ABEQ && a != ABNE { - continue - } - - copy: - for { - r = ctxt.NewProg() - *r = *p - if r.Mark&FOLL == 0 { - fmt.Printf("can't happen 1\n") - } - r.Mark |= FOLL - if p != q { - p = p.Link - (*last).Link = r - *last = r - continue - } - - (*last).Link = r - *last = r - if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF { - return - } - r.As = ABNE - if a == ABNE { - r.As = ABEQ - } - r.Pcond = p.Link - r.Link = p.Pcond - if r.Link.Mark&FOLL == 0 { - xfol(ctxt, r.Link, last) - } - if r.Pcond.Mark&FOLL == 0 { - fmt.Printf("can't happen 2\n") - } - return - } - } - - a = AB - q = ctxt.NewProg() - q.As = a - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - p.Mark |= FOLL - (*last).Link = p - *last = p - if a == AB || (a == obj.ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF { - return - } - - if p.Pcond != nil { - if a != ABL && a != ABX && p.Link != nil { - q = obj.Brchain(ctxt, p.Link) - if a != obj.ATEXT { - if q != nil && (q.Mark&FOLL != 0) { - p.As = relinv(a) - p.Link = p.Pcond - p.Pcond = q - } - } - - xfol(ctxt, p.Link, last) - q = obj.Brchain(ctxt, p.Pcond) - if q == nil { - q = p.Pcond - } - if q.Mark&FOLL != 0 { - p.Pcond = q - return - } - - p = q - goto loop - } - } - - p = p.Link - goto loop -} - -var unaryDst = map[obj.As]bool{ - ASWI: true, - AWORD: true, -} - -var Linkarm = obj.LinkArch{ - Arch: sys.ArchARM, - Preprocess: preprocess, - Assemble: span5, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, -} diff --git a/vendor/github.com/google/gops/internal/obj/arm64/a.out.go b/vendor/github.com/google/gops/internal/obj/arm64/a.out.go deleted file mode 100644 index b3a27d43..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm64/a.out.go +++ /dev/null @@ -1,719 +0,0 @@ -// cmd/7c/7.out.h from Vita Nuova. -// https://code.google.com/p/ken-cc/source/browse/src/cmd/7c/7.out.h -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm64 - -import "github.com/google/gops/internal/obj" - -const ( - NSNAME = 8 - NSYM = 50 - NREG = 32 /* number of general registers */ - NFREG = 32 /* number of floating point registers */ -) - -// General purpose registers, kept in the low bits of Prog.Reg. -const ( - // integer - REG_R0 = obj.RBaseARM64 + iota - REG_R1 - REG_R2 - REG_R3 - REG_R4 - REG_R5 - REG_R6 - REG_R7 - REG_R8 - REG_R9 - REG_R10 - REG_R11 - REG_R12 - REG_R13 - REG_R14 - REG_R15 - REG_R16 - REG_R17 - REG_R18 - REG_R19 - REG_R20 - REG_R21 - REG_R22 - REG_R23 - REG_R24 - REG_R25 - REG_R26 - REG_R27 - REG_R28 - REG_R29 - REG_R30 - REG_R31 - - // scalar floating point - REG_F0 - REG_F1 - REG_F2 - REG_F3 - REG_F4 - REG_F5 - REG_F6 - REG_F7 - REG_F8 - REG_F9 - REG_F10 - REG_F11 - REG_F12 - REG_F13 - REG_F14 - REG_F15 - REG_F16 - REG_F17 - REG_F18 - REG_F19 - REG_F20 - REG_F21 - REG_F22 - REG_F23 - REG_F24 - REG_F25 - REG_F26 - REG_F27 - REG_F28 - REG_F29 - REG_F30 - REG_F31 - - // SIMD - REG_V0 - REG_V1 - REG_V2 - REG_V3 - REG_V4 - REG_V5 - REG_V6 - REG_V7 - REG_V8 - REG_V9 - REG_V10 - REG_V11 - REG_V12 - REG_V13 - REG_V14 - REG_V15 - REG_V16 - REG_V17 - REG_V18 - REG_V19 - REG_V20 - REG_V21 - REG_V22 - REG_V23 - REG_V24 - REG_V25 - REG_V26 - REG_V27 - REG_V28 - REG_V29 - REG_V30 - REG_V31 - - // The EQ in - // CSET EQ, R0 - // is encoded as TYPE_REG, even though it's not really a register. - COND_EQ - COND_NE - COND_HS - COND_LO - COND_MI - COND_PL - COND_VS - COND_VC - COND_HI - COND_LS - COND_GE - COND_LT - COND_GT - COND_LE - COND_AL - COND_NV - - REG_RSP = REG_V31 + 32 // to differentiate ZR/SP, REG_RSP&0x1f = 31 -) - -// Not registers, but flags that can be combined with regular register -// constants to indicate extended register conversion. When checking, -// you should subtract obj.RBaseARM64 first. From this difference, bit 11 -// indicates extended register, bits 8-10 select the conversion mode. -const REG_EXT = obj.RBaseARM64 + 1<<11 - -const ( - REG_UXTB = REG_EXT + iota<<8 - REG_UXTH - REG_UXTW - REG_UXTX - REG_SXTB - REG_SXTH - REG_SXTW - REG_SXTX -) - -// Special registers, after subtracting obj.RBaseARM64, bit 12 indicates -// a special register and the low bits select the register. -const ( - REG_SPECIAL = obj.RBaseARM64 + 1<<12 + iota - REG_DAIF - REG_NZCV - REG_FPSR - REG_FPCR - REG_SPSR_EL1 - REG_ELR_EL1 - REG_SPSR_EL2 - REG_ELR_EL2 - REG_CurrentEL - REG_SP_EL0 - REG_SPSel - REG_DAIFSet - REG_DAIFClr -) - -// Register assignments: -// -// compiler allocates R0 up as temps -// compiler allocates register variables R7-R25 -// compiler allocates external registers R26 down -// -// compiler allocates register variables F7-F26 -// compiler allocates external registers F26 down -const ( - REGMIN = REG_R7 // register variables allocated from here to REGMAX - REGRT1 = REG_R16 // ARM64 IP0, for external linker, runtime, duffzero and duffcopy - REGRT2 = REG_R17 // ARM64 IP1, for external linker, runtime, duffcopy - REGPR = REG_R18 // ARM64 platform register, unused in the Go toolchain - REGMAX = REG_R25 - - REGCTXT = REG_R26 // environment for closures - REGTMP = REG_R27 // reserved for liblink - REGG = REG_R28 // G - REGFP = REG_R29 // frame pointer, unused in the Go toolchain - REGLINK = REG_R30 - - // ARM64 uses R31 as both stack pointer and zero register, - // depending on the instruction. To differentiate RSP from ZR, - // we use a different numeric value for REGZERO and REGSP. - REGZERO = REG_R31 - REGSP = REG_RSP - - FREGRET = REG_F0 - FREGMIN = REG_F7 // first register variable - FREGMAX = REG_F26 // last register variable for 7g only - FREGEXT = REG_F26 // first external register -) - -const ( - BIG = 2048 - 8 -) - -const ( - /* mark flags */ - LABEL = 1 << iota - LEAF - FLOAT - BRANCH - LOAD - FCMP - SYNC - LIST - FOLL - NOSCHED -) - -const ( - C_NONE = iota - C_REG // R0..R30 - C_RSP // R0..R30, RSP - C_FREG // F0..F31 - C_VREG // V0..V31 - C_PAIR // (Rn, Rm) - C_SHIFT // Rn<<2 - C_EXTREG // Rn.UXTB<<3 - C_SPR // REG_NZCV - C_COND // EQ, NE, etc - - C_ZCON // $0 or ZR - C_ADDCON0 // 12-bit unsigned, unshifted - C_ADDCON // 12-bit unsigned, shifted left by 0 or 12 - C_MOVCON // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16 - C_BITCON // bitfield and logical immediate masks - C_ABCON0 // could be C_ADDCON0 or C_BITCON - C_ABCON // could be C_ADDCON or C_BITCON - C_MBCON // could be C_MOVCON or C_BITCON - C_LCON // 32-bit constant - C_VCON // 64-bit constant - C_FCON // floating-point constant - C_VCONADDR // 64-bit memory address - - C_AACON // ADDCON offset in auto constant $a(FP) - C_LACON // 32-bit offset in auto constant $a(FP) - C_AECON // ADDCON offset in extern constant $e(SB) - - // TODO(aram): only one branch class should be enough - C_SBRA // for TYPE_BRANCH - C_LBRA - - C_NPAUTO // -512 <= x < 0, 0 mod 8 - C_NSAUTO // -256 <= x < 0 - C_PSAUTO // 0 to 255 - C_PPAUTO // 0 to 504, 0 mod 8 - C_UAUTO4K // 0 to 4095 - C_UAUTO8K // 0 to 8190, 0 mod 2 - C_UAUTO16K // 0 to 16380, 0 mod 4 - C_UAUTO32K // 0 to 32760, 0 mod 8 - C_UAUTO64K // 0 to 65520, 0 mod 16 - C_LAUTO // any other 32-bit constant - - C_SEXT1 // 0 to 4095, direct - C_SEXT2 // 0 to 8190 - C_SEXT4 // 0 to 16380 - C_SEXT8 // 0 to 32760 - C_SEXT16 // 0 to 65520 - C_LEXT - - // TODO(aram): s/AUTO/INDIR/ - C_ZOREG // 0(R) - C_NPOREG // mirror NPAUTO, etc - C_NSOREG - C_PSOREG - C_PPOREG - C_UOREG4K - C_UOREG8K - C_UOREG16K - C_UOREG32K - C_UOREG64K - C_LOREG - - C_ADDR // TODO(aram): explain difference from C_VCONADDR - - // The GOT slot for a symbol in -dynlink mode. - C_GOTADDR - - // TLS "var" in local exec mode: will become a constant offset from - // thread local base that is ultimately chosen by the program linker. - C_TLS_LE - - // TLS "var" in initial exec mode: will become a memory address (chosen - // by the program linker) that the dynamic linker will fill with the - // offset from the thread local base. - C_TLS_IE - - C_ROFF // register offset (including register extended) - - C_GOK - C_TEXTSIZE - C_NCLASS // must be last -) - -const ( - C_XPRE = 1 << 6 // match arm.C_WBIT, so Prog.String know how to print it - C_XPOST = 1 << 5 // match arm.C_PBIT, so Prog.String know how to print it -) - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm64 - -const ( - AADC = obj.ABaseARM64 + obj.A_ARCHSPECIFIC + iota - AADCS - AADCSW - AADCW - AADD - AADDS - AADDSW - AADDW - AADR - AADRP - AAND - AANDS - AANDSW - AANDW - AASR - AASRW - AAT - ABFI - ABFIW - ABFM - ABFMW - ABFXIL - ABFXILW - ABIC - ABICS - ABICSW - ABICW - ABRK - ACBNZ - ACBNZW - ACBZ - ACBZW - ACCMN - ACCMNW - ACCMP - ACCMPW - ACINC - ACINCW - ACINV - ACINVW - ACLREX - ACLS - ACLSW - ACLZ - ACLZW - ACMN - ACMNW - ACMP - ACMPW - ACNEG - ACNEGW - ACRC32B - ACRC32CB - ACRC32CH - ACRC32CW - ACRC32CX - ACRC32H - ACRC32W - ACRC32X - ACSEL - ACSELW - ACSET - ACSETM - ACSETMW - ACSETW - ACSINC - ACSINCW - ACSINV - ACSINVW - ACSNEG - ACSNEGW - ADC - ADCPS1 - ADCPS2 - ADCPS3 - ADMB - ADRPS - ADSB - AEON - AEONW - AEOR - AEORW - AERET - AEXTR - AEXTRW - AHINT - AHLT - AHVC - AIC - AISB - ALDAR - ALDARB - ALDARH - ALDARW - ALDAXP - ALDAXPW - ALDAXR - ALDAXRB - ALDAXRH - ALDAXRW - ALDP - ALDXR - ALDXRB - ALDXRH - ALDXRW - ALDXP - ALDXPW - ALSL - ALSLW - ALSR - ALSRW - AMADD - AMADDW - AMNEG - AMNEGW - AMOVK - AMOVKW - AMOVN - AMOVNW - AMOVZ - AMOVZW - AMRS - AMSR - AMSUB - AMSUBW - AMUL - AMULW - AMVN - AMVNW - ANEG - ANEGS - ANEGSW - ANEGW - ANGC - ANGCS - ANGCSW - ANGCW - AORN - AORNW - AORR - AORRW - APRFM - APRFUM - ARBIT - ARBITW - AREM - AREMW - AREV - AREV16 - AREV16W - AREV32 - AREVW - AROR - ARORW - ASBC - ASBCS - ASBCSW - ASBCW - ASBFIZ - ASBFIZW - ASBFM - ASBFMW - ASBFX - ASBFXW - ASDIV - ASDIVW - ASEV - ASEVL - ASMADDL - ASMC - ASMNEGL - ASMSUBL - ASMULH - ASMULL - ASTXR - ASTXRB - ASTXRH - ASTXP - ASTXPW - ASTXRW - ASTLP - ASTLPW - ASTLR - ASTLRB - ASTLRH - ASTLRW - ASTLXP - ASTLXPW - ASTLXR - ASTLXRB - ASTLXRH - ASTLXRW - ASTP - ASUB - ASUBS - ASUBSW - ASUBW - ASVC - ASXTB - ASXTBW - ASXTH - ASXTHW - ASXTW - ASYS - ASYSL - ATBNZ - ATBZ - ATLBI - ATST - ATSTW - AUBFIZ - AUBFIZW - AUBFM - AUBFMW - AUBFX - AUBFXW - AUDIV - AUDIVW - AUMADDL - AUMNEGL - AUMSUBL - AUMULH - AUMULL - AUREM - AUREMW - AUXTB - AUXTH - AUXTW - AUXTBW - AUXTHW - AWFE - AWFI - AYIELD - AMOVB - AMOVBU - AMOVH - AMOVHU - AMOVW - AMOVWU - AMOVD - AMOVNP - AMOVNPW - AMOVP - AMOVPD - AMOVPQ - AMOVPS - AMOVPSW - AMOVPW - ABEQ - ABNE - ABCS - ABHS - ABCC - ABLO - ABMI - ABPL - ABVS - ABVC - ABHI - ABLS - ABGE - ABLT - ABGT - ABLE - AFABSD - AFABSS - AFADDD - AFADDS - AFCCMPD - AFCCMPED - AFCCMPS - AFCCMPES - AFCMPD - AFCMPED - AFCMPES - AFCMPS - AFCVTSD - AFCVTDS - AFCVTZSD - AFCVTZSDW - AFCVTZSS - AFCVTZSSW - AFCVTZUD - AFCVTZUDW - AFCVTZUS - AFCVTZUSW - AFDIVD - AFDIVS - AFMOVD - AFMOVS - AFMULD - AFMULS - AFNEGD - AFNEGS - AFSQRTD - AFSQRTS - AFSUBD - AFSUBS - ASCVTFD - ASCVTFS - ASCVTFWD - ASCVTFWS - AUCVTFD - AUCVTFS - AUCVTFWD - AUCVTFWS - AWORD - ADWORD - AFCSELS - AFCSELD - AFMAXS - AFMINS - AFMAXD - AFMIND - AFMAXNMS - AFMAXNMD - AFNMULS - AFNMULD - AFRINTNS - AFRINTND - AFRINTPS - AFRINTPD - AFRINTMS - AFRINTMD - AFRINTZS - AFRINTZD - AFRINTAS - AFRINTAD - AFRINTXS - AFRINTXD - AFRINTIS - AFRINTID - AFMADDS - AFMADDD - AFMSUBS - AFMSUBD - AFNMADDS - AFNMADDD - AFNMSUBS - AFNMSUBD - AFMINNMS - AFMINNMD - AFCVTDH - AFCVTHS - AFCVTHD - AFCVTSH - AAESD - AAESE - AAESIMC - AAESMC - ASHA1C - ASHA1H - ASHA1M - ASHA1P - ASHA1SU0 - ASHA1SU1 - ASHA256H - ASHA256H2 - ASHA256SU0 - ASHA256SU1 - ALAST - AB = obj.AJMP - ABL = obj.ACALL -) - -const ( - // shift types - SHIFT_LL = 0 << 22 - SHIFT_LR = 1 << 22 - SHIFT_AR = 2 << 22 -) diff --git a/vendor/github.com/google/gops/internal/obj/arm64/anames.go b/vendor/github.com/google/gops/internal/obj/arm64/anames.go deleted file mode 100644 index d1334596..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm64/anames.go +++ /dev/null @@ -1,370 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p arm64 -// Do not edit. - -package arm64 - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "ADC", - "ADCS", - "ADCSW", - "ADCW", - "ADD", - "ADDS", - "ADDSW", - "ADDW", - "ADR", - "ADRP", - "AND", - "ANDS", - "ANDSW", - "ANDW", - "ASR", - "ASRW", - "AT", - "BFI", - "BFIW", - "BFM", - "BFMW", - "BFXIL", - "BFXILW", - "BIC", - "BICS", - "BICSW", - "BICW", - "BRK", - "CBNZ", - "CBNZW", - "CBZ", - "CBZW", - "CCMN", - "CCMNW", - "CCMP", - "CCMPW", - "CINC", - "CINCW", - "CINV", - "CINVW", - "CLREX", - "CLS", - "CLSW", - "CLZ", - "CLZW", - "CMN", - "CMNW", - "CMP", - "CMPW", - "CNEG", - "CNEGW", - "CRC32B", - "CRC32CB", - "CRC32CH", - "CRC32CW", - "CRC32CX", - "CRC32H", - "CRC32W", - "CRC32X", - "CSEL", - "CSELW", - "CSET", - "CSETM", - "CSETMW", - "CSETW", - "CSINC", - "CSINCW", - "CSINV", - "CSINVW", - "CSNEG", - "CSNEGW", - "DC", - "DCPS1", - "DCPS2", - "DCPS3", - "DMB", - "DRPS", - "DSB", - "EON", - "EONW", - "EOR", - "EORW", - "ERET", - "EXTR", - "EXTRW", - "HINT", - "HLT", - "HVC", - "IC", - "ISB", - "LDAR", - "LDARB", - "LDARH", - "LDARW", - "LDAXP", - "LDAXPW", - "LDAXR", - "LDAXRB", - "LDAXRH", - "LDAXRW", - "LDP", - "LDXR", - "LDXRB", - "LDXRH", - "LDXRW", - "LDXP", - "LDXPW", - "LSL", - "LSLW", - "LSR", - "LSRW", - "MADD", - "MADDW", - "MNEG", - "MNEGW", - "MOVK", - "MOVKW", - "MOVN", - "MOVNW", - "MOVZ", - "MOVZW", - "MRS", - "MSR", - "MSUB", - "MSUBW", - "MUL", - "MULW", - "MVN", - "MVNW", - "NEG", - "NEGS", - "NEGSW", - "NEGW", - "NGC", - "NGCS", - "NGCSW", - "NGCW", - "ORN", - "ORNW", - "ORR", - "ORRW", - "PRFM", - "PRFUM", - "RBIT", - "RBITW", - "REM", - "REMW", - "REV", - "REV16", - "REV16W", - "REV32", - "REVW", - "ROR", - "RORW", - "SBC", - "SBCS", - "SBCSW", - "SBCW", - "SBFIZ", - "SBFIZW", - "SBFM", - "SBFMW", - "SBFX", - "SBFXW", - "SDIV", - "SDIVW", - "SEV", - "SEVL", - "SMADDL", - "SMC", - "SMNEGL", - "SMSUBL", - "SMULH", - "SMULL", - "STXR", - "STXRB", - "STXRH", - "STXP", - "STXPW", - "STXRW", - "STLP", - "STLPW", - "STLR", - "STLRB", - "STLRH", - "STLRW", - "STLXP", - "STLXPW", - "STLXR", - "STLXRB", - "STLXRH", - "STLXRW", - "STP", - "SUB", - "SUBS", - "SUBSW", - "SUBW", - "SVC", - "SXTB", - "SXTBW", - "SXTH", - "SXTHW", - "SXTW", - "SYS", - "SYSL", - "TBNZ", - "TBZ", - "TLBI", - "TST", - "TSTW", - "UBFIZ", - "UBFIZW", - "UBFM", - "UBFMW", - "UBFX", - "UBFXW", - "UDIV", - "UDIVW", - "UMADDL", - "UMNEGL", - "UMSUBL", - "UMULH", - "UMULL", - "UREM", - "UREMW", - "UXTB", - "UXTH", - "UXTW", - "UXTBW", - "UXTHW", - "WFE", - "WFI", - "YIELD", - "MOVB", - "MOVBU", - "MOVH", - "MOVHU", - "MOVW", - "MOVWU", - "MOVD", - "MOVNP", - "MOVNPW", - "MOVP", - "MOVPD", - "MOVPQ", - "MOVPS", - "MOVPSW", - "MOVPW", - "BEQ", - "BNE", - "BCS", - "BHS", - "BCC", - "BLO", - "BMI", - "BPL", - "BVS", - "BVC", - "BHI", - "BLS", - "BGE", - "BLT", - "BGT", - "BLE", - "FABSD", - "FABSS", - "FADDD", - "FADDS", - "FCCMPD", - "FCCMPED", - "FCCMPS", - "FCCMPES", - "FCMPD", - "FCMPED", - "FCMPES", - "FCMPS", - "FCVTSD", - "FCVTDS", - "FCVTZSD", - "FCVTZSDW", - "FCVTZSS", - "FCVTZSSW", - "FCVTZUD", - "FCVTZUDW", - "FCVTZUS", - "FCVTZUSW", - "FDIVD", - "FDIVS", - "FMOVD", - "FMOVS", - "FMULD", - "FMULS", - "FNEGD", - "FNEGS", - "FSQRTD", - "FSQRTS", - "FSUBD", - "FSUBS", - "SCVTFD", - "SCVTFS", - "SCVTFWD", - "SCVTFWS", - "UCVTFD", - "UCVTFS", - "UCVTFWD", - "UCVTFWS", - "WORD", - "DWORD", - "FCSELS", - "FCSELD", - "FMAXS", - "FMINS", - "FMAXD", - "FMIND", - "FMAXNMS", - "FMAXNMD", - "FNMULS", - "FNMULD", - "FRINTNS", - "FRINTND", - "FRINTPS", - "FRINTPD", - "FRINTMS", - "FRINTMD", - "FRINTZS", - "FRINTZD", - "FRINTAS", - "FRINTAD", - "FRINTXS", - "FRINTXD", - "FRINTIS", - "FRINTID", - "FMADDS", - "FMADDD", - "FMSUBS", - "FMSUBD", - "FNMADDS", - "FNMADDD", - "FNMSUBS", - "FNMSUBD", - "FMINNMS", - "FMINNMD", - "FCVTDH", - "FCVTHS", - "FCVTHD", - "FCVTSH", - "AESD", - "AESE", - "AESIMC", - "AESMC", - "SHA1C", - "SHA1H", - "SHA1M", - "SHA1P", - "SHA1SU0", - "SHA1SU1", - "SHA256H", - "SHA256H2", - "SHA256SU0", - "SHA256SU1", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/arm64/anames7.go b/vendor/github.com/google/gops/internal/obj/arm64/anames7.go deleted file mode 100644 index d55b34f9..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm64/anames7.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015 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 arm64 - -var cnames7 = []string{ - "NONE", - "REG", - "RSP", - "FREG", - "VREG", - "PAIR", - "SHIFT", - "EXTREG", - "SPR", - "COND", - "ZCON", - "ADDCON0", - "ADDCON", - "MOVCON", - "BITCON", - "ABCON0", - "ABCON", - "MBCON", - "LCON", - "VCON", - "FCON", - "VCONADDR", - "AACON", - "LACON", - "AECON", - "SBRA", - "LBRA", - "NPAUTO", - "NSAUTO", - "PSAUTO", - "PPAUTO", - "UAUTO4K", - "UAUTO8K", - "UAUTO16K", - "UAUTO32K", - "UAUTO64K", - "LAUTO", - "SEXT1", - "SEXT2", - "SEXT4", - "SEXT8", - "SEXT16", - "LEXT", - "ZOREG", - "NPOREG", - "NSOREG", - "PSOREG", - "PPOREG", - "UOREG4K", - "UOREG8K", - "UOREG16K", - "UOREG32K", - "UOREG64K", - "LOREG", - "ADDR", - "GOTADDR", - "TLS_LE", - "TLS_IE", - "ROFF", - "GOK", - "TEXTSIZE", - "NCLASS", -} diff --git a/vendor/github.com/google/gops/internal/obj/arm64/asm7.go b/vendor/github.com/google/gops/internal/obj/arm64/asm7.go deleted file mode 100644 index a6dae2e4..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm64/asm7.go +++ /dev/null @@ -1,4374 +0,0 @@ -// cmd/7l/asm.c, cmd/7l/asmout.c, cmd/7l/optab.c, cmd/7l/span.c, cmd/ld/sub.c, cmd/ld/mod.c, from Vita Nuova. -// https://code.google.com/p/ken-cc/source/browse/ -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm64 - -import ( - "fmt" - "log" - "math" - "sort" - - "github.com/google/gops/internal/obj" -) - -const ( - funcAlign = 16 -) - -const ( - REGFROM = 1 -) - -type Optab struct { - as obj.As - a1 uint8 - a2 uint8 - a3 uint8 - type_ int8 - size int8 - param int16 - flag int8 - scond uint16 -} - -var oprange [ALAST & obj.AMask][]Optab - -var xcmp [C_NCLASS][C_NCLASS]bool - -const ( - S32 = 0 << 31 - S64 = 1 << 31 - Sbit = 1 << 29 - LSL0_32 = 2 << 13 - LSL0_64 = 3 << 13 -) - -func OPDP2(x uint32) uint32 { - return 0<<30 | 0<<29 | 0xd6<<21 | x<<10 -} - -func OPDP3(sf uint32, op54 uint32, op31 uint32, o0 uint32) uint32 { - return sf<<31 | op54<<29 | 0x1B<<24 | op31<<21 | o0<<15 -} - -func OPBcc(x uint32) uint32 { - return 0x2A<<25 | 0<<24 | 0<<4 | x&15 -} - -func OPBLR(x uint32) uint32 { - /* x=0, JMP; 1, CALL; 2, RET */ - return 0x6B<<25 | 0<<23 | x<<21 | 0x1F<<16 | 0<<10 -} - -func SYSOP(l uint32, op0 uint32, op1 uint32, crn uint32, crm uint32, op2 uint32, rt uint32) uint32 { - return 0x354<<22 | l<<21 | op0<<19 | op1<<16 | crn&15<<12 | crm&15<<8 | op2<<5 | rt -} - -func SYSHINT(x uint32) uint32 { - return SYSOP(0, 0, 3, 2, 0, x, 0x1F) -} - -func LDSTR12U(sz uint32, v uint32, opc uint32) uint32 { - return sz<<30 | 7<<27 | v<<26 | 1<<24 | opc<<22 -} - -func LDSTR9S(sz uint32, v uint32, opc uint32) uint32 { - return sz<<30 | 7<<27 | v<<26 | 0<<24 | opc<<22 -} - -func LD2STR(o uint32) uint32 { - return o &^ (3 << 22) -} - -func LDSTX(sz uint32, o2 uint32, l uint32, o1 uint32, o0 uint32) uint32 { - return sz<<30 | 0x8<<24 | o2<<23 | l<<22 | o1<<21 | o0<<15 -} - -func FPCMP(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 { - return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<14 | 8<<10 | op2 -} - -func FPCCMP(m uint32, s uint32, type_ uint32, op uint32) uint32 { - return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | 1<<10 | op<<4 -} - -func FPOP1S(m uint32, s uint32, type_ uint32, op uint32) uint32 { - return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<15 | 0x10<<10 -} - -func FPOP2S(m uint32, s uint32, type_ uint32, op uint32) uint32 { - return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<12 | 2<<10 -} - -func FPCVTI(sf uint32, s uint32, type_ uint32, rmode uint32, op uint32) uint32 { - return sf<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | rmode<<19 | op<<16 | 0<<10 -} - -func ADR(p uint32, o uint32, rt uint32) uint32 { - return p<<31 | (o&3)<<29 | 0x10<<24 | ((o>>2)&0x7FFFF)<<5 | rt&31 -} - -func OPBIT(x uint32) uint32 { - return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10 -} - -const ( - LFROM = 1 << 0 - LTO = 1 << 1 -) - -var optab = []Optab{ - /* struct Optab: - OPCODE, from, prog->reg, to, type,size,param,flag,scond */ - {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0}, - - /* arithmetic operations */ - {AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AADC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AADC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {ANEG, C_REG, C_NONE, C_REG, 25, 4, 0, 0, 0}, - {ANEG, C_NONE, C_NONE, C_REG, 25, 4, 0, 0, 0}, - {ANGC, C_REG, C_NONE, C_REG, 17, 4, 0, 0, 0}, - {ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0}, - {AADD, C_ADDCON, C_RSP, C_RSP, 2, 4, 0, 0, 0}, - {AADD, C_ADDCON, C_NONE, C_RSP, 2, 4, 0, 0, 0}, - {ACMP, C_ADDCON, C_RSP, C_NONE, 2, 4, 0, 0, 0}, - {AADD, C_MOVCON, C_RSP, C_RSP, 62, 8, 0, 0, 0}, - {AADD, C_MOVCON, C_NONE, C_RSP, 62, 8, 0, 0, 0}, - {ACMP, C_MOVCON, C_RSP, C_NONE, 62, 8, 0, 0, 0}, - {AADD, C_BITCON, C_RSP, C_RSP, 62, 8, 0, 0, 0}, - {AADD, C_BITCON, C_NONE, C_RSP, 62, 8, 0, 0, 0}, - {ACMP, C_BITCON, C_RSP, C_NONE, 62, 8, 0, 0, 0}, - {AADD, C_VCON, C_RSP, C_RSP, 13, 8, 0, LFROM, 0}, - {AADD, C_VCON, C_NONE, C_RSP, 13, 8, 0, LFROM, 0}, - {ACMP, C_VCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0}, - {AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0}, - {AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0}, - {ANEG, C_SHIFT, C_NONE, C_REG, 26, 4, 0, 0, 0}, - {AADD, C_REG, C_RSP, C_RSP, 27, 4, 0, 0, 0}, - {AADD, C_REG, C_NONE, C_RSP, 27, 4, 0, 0, 0}, - {ACMP, C_REG, C_RSP, C_NONE, 27, 4, 0, 0, 0}, - {AADD, C_EXTREG, C_RSP, C_RSP, 27, 4, 0, 0, 0}, - {AADD, C_EXTREG, C_NONE, C_RSP, 27, 4, 0, 0, 0}, - {AMVN, C_EXTREG, C_NONE, C_RSP, 27, 4, 0, 0, 0}, - {ACMP, C_EXTREG, C_RSP, C_NONE, 27, 4, 0, 0, 0}, - {AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - - /* logical operations */ - {AAND, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {ABIC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {ABIC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AAND, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0}, - {AAND, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0}, - {ABIC, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0}, - {ABIC, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0}, - {AAND, C_MOVCON, C_REG, C_REG, 62, 8, 0, 0, 0}, - {AAND, C_MOVCON, C_NONE, C_REG, 62, 8, 0, 0, 0}, - {ABIC, C_MOVCON, C_REG, C_REG, 62, 8, 0, 0, 0}, - {ABIC, C_MOVCON, C_NONE, C_REG, 62, 8, 0, 0, 0}, - {AAND, C_VCON, C_REG, C_REG, 28, 8, 0, LFROM, 0}, - {AAND, C_VCON, C_NONE, C_REG, 28, 8, 0, LFROM, 0}, - {ABIC, C_VCON, C_REG, C_REG, 28, 8, 0, LFROM, 0}, - {ABIC, C_VCON, C_NONE, C_REG, 28, 8, 0, LFROM, 0}, - {AAND, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0}, - {AAND, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {ABIC, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0}, - {ABIC, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {AMOVD, C_RSP, C_NONE, C_RSP, 24, 4, 0, 0, 0}, - {AMVN, C_REG, C_NONE, C_REG, 24, 4, 0, 0, 0}, - {AMOVB, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVHU */ - {AMOVW, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVWU */ - /* TODO: MVN C_SHIFT */ - - /* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */ - {AMOVW, C_MOVCON, C_NONE, C_REG, 32, 4, 0, 0, 0}, - {AMOVD, C_MOVCON, C_NONE, C_REG, 32, 4, 0, 0, 0}, - - // TODO: these don't work properly. - // { AMOVW, C_ADDCON, C_NONE, C_REG, 2, 4, 0 , 0}, - // { AMOVD, C_ADDCON, C_NONE, C_REG, 2, 4, 0 , 0}, - {AMOVW, C_BITCON, C_NONE, C_REG, 32, 4, 0, 0, 0}, - {AMOVD, C_BITCON, C_NONE, C_REG, 32, 4, 0, 0, 0}, - - {AMOVK, C_VCON, C_NONE, C_REG, 33, 4, 0, 0, 0}, - {AMOVD, C_AACON, C_NONE, C_REG, 4, 4, REGFROM, 0, 0}, - {ASDIV, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {ASDIV, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, - {ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, - {AB, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, - {ABL, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0}, - {ABL, C_REG, C_NONE, C_REG, 6, 4, 0, 0, 0}, - {ABL, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, - {obj.ARET, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0}, - {obj.ARET, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, - {AADRP, C_SBRA, C_NONE, C_REG, 60, 4, 0, 0, 0}, - {AADR, C_SBRA, C_NONE, C_REG, 61, 4, 0, 0, 0}, - {ABFM, C_VCON, C_REG, C_REG, 42, 4, 0, 0, 0}, - {ABFI, C_VCON, C_REG, C_REG, 43, 4, 0, 0, 0}, - {AEXTR, C_VCON, C_REG, C_REG, 44, 4, 0, 0, 0}, - {ASXTB, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, - {ACLS, C_REG, C_NONE, C_REG, 46, 4, 0, 0, 0}, - {ABEQ, C_NONE, C_NONE, C_SBRA, 7, 4, 0, 0, 0}, - {ALSL, C_VCON, C_REG, C_REG, 8, 4, 0, 0, 0}, - {ALSL, C_VCON, C_NONE, C_REG, 8, 4, 0, 0, 0}, - {ALSL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0}, - {ALSL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0}, - {ASVC, C_NONE, C_NONE, C_VCON, 10, 4, 0, 0, 0}, - {ASVC, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0}, - {ADWORD, C_NONE, C_NONE, C_VCON, 11, 8, 0, 0, 0}, - {ADWORD, C_NONE, C_NONE, C_LEXT, 11, 8, 0, 0, 0}, - {ADWORD, C_NONE, C_NONE, C_ADDR, 11, 8, 0, 0, 0}, - {ADWORD, C_NONE, C_NONE, C_LACON, 11, 8, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_LCON, 14, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_LEXT, 14, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_ADDR, 14, 4, 0, 0, 0}, - {AMOVW, C_VCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0}, - {AMOVW, C_VCONADDR, C_NONE, C_REG, 68, 8, 0, 0, 0}, - {AMOVD, C_VCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0}, - {AMOVD, C_VCONADDR, C_NONE, C_REG, 68, 8, 0, 0, 0}, - {AMOVB, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AMOVD, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AMOVB, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0}, - {AMOVBU, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0}, - {AMOVH, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0}, - {AMOVW, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0}, - {AMOVD, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0}, - {AMOVD, C_GOTADDR, C_NONE, C_REG, 71, 8, 0, 0, 0}, - {AMOVD, C_TLS_LE, C_NONE, C_REG, 69, 4, 0, 0, 0}, - {AMOVD, C_TLS_IE, C_NONE, C_REG, 70, 8, 0, 0, 0}, - {AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0}, - {AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0}, - {AMADD, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0}, - {AREM, C_REG, C_REG, C_REG, 16, 8, 0, 0, 0}, - {AREM, C_REG, C_NONE, C_REG, 16, 8, 0, 0, 0}, - {ACSEL, C_COND, C_REG, C_REG, 18, 4, 0, 0, 0}, /* from3 optional */ - {ACSET, C_COND, C_NONE, C_REG, 18, 4, 0, 0, 0}, - {ACCMN, C_COND, C_REG, C_VCON, 19, 4, 0, 0, 0}, /* from3 either C_REG or C_VCON */ - - /* scaled 12-bit unsigned displacement store */ - {AMOVB, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0}, - {AMOVB, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0}, - - {AMOVH, C_REG, C_NONE, C_UAUTO8K, 20, 4, REGSP, 0, 0}, - {AMOVH, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_UOREG8K, 20, 4, 0, 0, 0}, - - {AMOVW, C_REG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0}, - {AMOVW, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0}, - - /* unscaled 9-bit signed displacement store */ - {AMOVB, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - {AMOVB, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - - {AMOVH, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - {AMOVH, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - {AMOVW, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - - {AMOVD, C_REG, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0}, - {AMOVD, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0}, - {AMOVD, C_REG, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0}, - {AMOVD, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - {AMOVD, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - - /* short displacement load */ - {AMOVB, C_UAUTO4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVB, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVB, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVB, C_UOREG4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVB, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - - {AMOVBU, C_UAUTO4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVBU, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVBU, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVBU, C_UOREG4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVBU, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - - {AMOVH, C_UAUTO8K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVH, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVH, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVH, C_UOREG8K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVH, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - - {AMOVW, C_UAUTO16K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVW, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVW, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVW, C_UOREG16K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVW, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - - {AMOVD, C_UAUTO32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVD, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVD, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVD, C_UOREG32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVD, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - - /* long displacement store */ - {AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0}, - {AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0}, - {AMOVH, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0}, - {AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0}, - {AMOVD, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0}, - {AMOVD, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0}, - - /* long displacement load */ - {AMOVB, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0}, - {AMOVB, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVB, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVH, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0}, - {AMOVH, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVH, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0}, - {AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVD, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0}, - {AMOVD, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - {AMOVD, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0}, - - /* load long effective stack address (load int32 offset and add) */ - {AMOVD, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0}, - - /* pre/post-indexed load (unscaled, signed 9-bit offset) */ - {AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, - {AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, - {AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, - {AMOVB, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, - {AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, - {AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, - {AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, - {AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, - {AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, - {AMOVB, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, - {AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, - {AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, - - /* pre/post-indexed store (unscaled, signed 9-bit offset) */ - {AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AMOVB, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, - {AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - {AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - {AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - {AMOVB, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - {AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - {AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - {AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, - - /* pre/post-indexed load/store register pair - (unscaled, signed 10-bit quad-aligned offset) */ - {ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE}, - {ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST}, - {ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPRE}, - {ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPOST}, - - /* special */ - {AMOVD, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0}, - {AMRS, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0}, - {AMOVD, C_REG, C_NONE, C_SPR, 36, 4, 0, 0, 0}, - {AMSR, C_REG, C_NONE, C_SPR, 36, 4, 0, 0, 0}, - {AMOVD, C_VCON, C_NONE, C_SPR, 37, 4, 0, 0, 0}, - {AMSR, C_VCON, C_NONE, C_SPR, 37, 4, 0, 0, 0}, - {AERET, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, - {AFMOVS, C_UAUTO16K, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, - {AFMOVS, C_NSAUTO, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, - {AFMOVS, C_ZOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0}, - {AFMOVS, C_UOREG16K, C_NONE, C_FREG, 21, 4, 0, 0, 0}, - {AFMOVS, C_NSOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0}, - {AFMOVD, C_UAUTO32K, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, - {AFMOVD, C_NSAUTO, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, - {AFMOVD, C_ZOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0}, - {AFMOVD, C_UOREG32K, C_NONE, C_FREG, 21, 4, 0, 0, 0}, - {AFMOVD, C_NSOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AFMOVS, C_FREG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AFMOVD, C_FREG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AFMOVD, C_FREG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AFMOVS, C_LAUTO, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, - {AFMOVS, C_LOREG, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, - {AFMOVD, C_LAUTO, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, - {AFMOVD, C_LOREG, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, - {AFMOVS, C_FREG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AFMOVS, C_ADDR, C_NONE, C_FREG, 65, 12, 0, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_ADDR, 64, 12, 0, 0, 0}, - {AFMOVD, C_ADDR, C_NONE, C_FREG, 65, 12, 0, 0, 0}, - {AFADDS, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AFADDS, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0}, - {AFADDS, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AFADDS, C_FCON, C_FREG, C_FREG, 54, 4, 0, 0, 0}, - {AFMOVS, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AFMOVD, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AFCVTZSD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0}, - {ASCVTFD, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0}, - {AFMOVS, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0}, - {AFMOVS, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0}, - {AFMOVD, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0}, - {AFMOVD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0}, - {AFCMPS, C_FREG, C_FREG, C_NONE, 56, 4, 0, 0, 0}, - {AFCMPS, C_FCON, C_FREG, C_NONE, 56, 4, 0, 0, 0}, - {AFCCMPS, C_COND, C_REG, C_VCON, 57, 4, 0, 0, 0}, - {AFCSELD, C_COND, C_REG, C_FREG, 18, 4, 0, 0, 0}, - {AFCVTSD, C_FREG, C_NONE, C_FREG, 29, 4, 0, 0, 0}, - {ACLREX, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0}, - {ACLREX, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0}, - {ACBZ, C_REG, C_NONE, C_SBRA, 39, 4, 0, 0, 0}, - {ATBZ, C_VCON, C_REG, C_SBRA, 40, 4, 0, 0, 0}, - {ASYS, C_VCON, C_NONE, C_NONE, 50, 4, 0, 0, 0}, - {ASYS, C_VCON, C_REG, C_NONE, 50, 4, 0, 0, 0}, - {ASYSL, C_VCON, C_NONE, C_REG, 50, 4, 0, 0, 0}, - {ADMB, C_VCON, C_NONE, C_NONE, 51, 4, 0, 0, 0}, - {AHINT, C_VCON, C_NONE, C_NONE, 52, 4, 0, 0, 0}, - {ALDAR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0}, - {ALDXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0}, - {ALDAXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0}, - {ALDXP, C_ZOREG, C_REG, C_REG, 58, 4, 0, 0, 0}, - {ASTLR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_NONE - {ASTXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG - {ASTLXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG - - // { ASTXP, C_REG, C_NONE, C_ZOREG, 59, 4, 0 , 0}, // TODO(aram): - - {AAESD, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0}, - {ASHA1C, C_VREG, C_REG, C_VREG, 1, 4, 0, 0, 0}, - - {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0}, - {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - {obj.APCDATA, C_VCON, C_NONE, C_VCON, 0, 0, 0, 0, 0}, - {obj.AFUNCDATA, C_VCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0}, - {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - {obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL - {obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL - - {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0}, -} - -/* - * valid pstate field values, and value to use in instruction - */ -var pstatefield = []struct { - a uint32 - b uint32 -}{ - {REG_SPSel, 0<<16 | 4<<12 | 5<<5}, - {REG_DAIFSet, 3<<16 | 4<<12 | 6<<5}, - {REG_DAIFClr, 3<<16 | 4<<12 | 7<<5}, -} - -var pool struct { - start uint32 - size uint32 -} - -func prasm(p *obj.Prog) { - fmt.Printf("%v\n", p) -} - -func span7(ctxt *obj.Link, cursym *obj.LSym) { - p := cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - ctxt.Cursym = cursym - ctxt.Autosize = int32(p.To.Offset&0xffffffff) + 8 - - if oprange[AAND&obj.AMask] == nil { - buildop(ctxt) - } - - bflag := 1 - c := int64(0) - p.Pc = c - var m int - var o *Optab - for p = p.Link; p != nil; p = p.Link { - ctxt.Curp = p - if p.As == ADWORD && (c&7) != 0 { - c += 4 - } - p.Pc = c - o = oplook(ctxt, p) - m = int(o.size) - if m == 0 { - if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { - ctxt.Diag("zero-width instruction\n%v", p) - } - continue - } - - switch o.flag & (LFROM | LTO) { - case LFROM: - addpool(ctxt, p, &p.From) - - case LTO: - addpool(ctxt, p, &p.To) - break - } - - if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */ - checkpool(ctxt, p, 0) - } - c += int64(m) - if ctxt.Blitrl != nil { - checkpool(ctxt, p, 1) - } - } - - cursym.Size = c - - /* - * if any procedure is large enough to - * generate a large SBRA branch, then - * generate extra passes putting branches - * around jmps to fix. this is rare. - */ - for bflag != 0 { - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f span1\n", obj.Cputime()) - } - bflag = 0 - c = 0 - for p = cursym.Text.Link; p != nil; p = p.Link { - if p.As == ADWORD && (c&7) != 0 { - c += 4 - } - p.Pc = c - o = oplook(ctxt, p) - - /* very large branches */ - if o.type_ == 7 && p.Pcond != nil { - otxt := p.Pcond.Pc - c - if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 { - q := ctxt.NewProg() - q.Link = p.Link - p.Link = q - q.As = AB - q.To.Type = obj.TYPE_BRANCH - q.Pcond = p.Pcond - p.Pcond = q - q = ctxt.NewProg() - q.Link = p.Link - p.Link = q - q.As = AB - q.To.Type = obj.TYPE_BRANCH - q.Pcond = q.Link.Link - bflag = 1 - } - } - m = int(o.size) - - if m == 0 { - if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { - ctxt.Diag("zero-width instruction\n%v", p) - } - continue - } - - c += int64(m) - } - } - - c += -c & (funcAlign - 1) - cursym.Size = c - - /* - * lay out the code, emitting code and data relocations. - */ - cursym.Grow(cursym.Size) - bp := cursym.P - psz := int32(0) - var i int - var out [6]uint32 - for p := cursym.Text.Link; p != nil; p = p.Link { - ctxt.Pc = p.Pc - ctxt.Curp = p - o = oplook(ctxt, p) - - // need to align DWORDs on 8-byte boundary. The ISA doesn't - // require it, but the various 64-bit loads we generate assume it. - if o.as == ADWORD && psz%8 != 0 { - bp[3] = 0 - bp[2] = bp[3] - bp[1] = bp[2] - bp[0] = bp[1] - bp = bp[4:] - psz += 4 - } - - if int(o.size) > 4*len(out) { - log.Fatalf("out array in span7 is too small, need at least %d for %v", o.size/4, p) - } - asmout(ctxt, p, o, out[:]) - for i = 0; i < int(o.size/4); i++ { - ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) - bp = bp[4:] - psz += 4 - } - } -} - -/* - * when the first reference to the literal pool threatens - * to go out of range of a 1Mb PC-relative offset - * drop the pool now, and branch round it. - */ -func checkpool(ctxt *obj.Link, p *obj.Prog, skip int) { - if pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(pool.size)-int64(pool.start)+8)) { - flushpool(ctxt, p, skip) - } else if p.Link == nil { - flushpool(ctxt, p, 2) - } -} - -func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) { - if ctxt.Blitrl != nil { - if skip != 0 { - if ctxt.Debugvlog != 0 && skip == 1 { - fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start) - } - q := ctxt.NewProg() - q.As = AB - q.To.Type = obj.TYPE_BRANCH - q.Pcond = p.Link - q.Link = ctxt.Blitrl - q.Lineno = p.Lineno - ctxt.Blitrl = q - } else if p.Pc+int64(pool.size)-int64(pool.start) < maxPCDisp { - return - } - - // The line number for constant pool entries doesn't really matter. - // We set it to the line number of the preceding instruction so that - // there are no deltas to encode in the pc-line tables. - for q := ctxt.Blitrl; q != nil; q = q.Link { - q.Lineno = p.Lineno - } - - ctxt.Elitrl.Link = p.Link - p.Link = ctxt.Blitrl - - ctxt.Blitrl = nil /* BUG: should refer back to values until out-of-range */ - ctxt.Elitrl = nil - pool.size = 0 - pool.start = 0 - } -} - -/* - * TODO: hash - */ -func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - c := aclass(ctxt, a) - lit := ctxt.Instoffset - t := *ctxt.NewProg() - t.As = AWORD - sz := 4 - - // MOVD foo(SB), R is actually - // MOVD addr, REGTMP - // MOVD REGTMP, R - // where addr is the address of the DWORD containing the address of foo. - if p.As == AMOVD || c == C_ADDR || c == C_VCON || int64(lit) != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) { - // conservative: don't know if we want signed or unsigned extension. - // in case of ambiguity, store 64-bit - t.As = ADWORD - sz = 8 - } - - switch c { - // TODO(aram): remove. - default: - if a.Name != obj.NAME_EXTERN { - fmt.Printf("addpool: %v in %v shouldn't go to default case\n", DRconv(c), p) - } - - t.To.Offset = a.Offset - t.To.Sym = a.Sym - t.To.Type = a.Type - t.To.Name = a.Name - - /* This is here because MOV uint12<<12, R is disabled in optab. - Because of this, we need to load the constant from memory. */ - case C_ADDCON: - fallthrough - - case C_PSAUTO, - C_PPAUTO, - C_UAUTO4K, - C_UAUTO8K, - C_UAUTO16K, - C_UAUTO32K, - C_UAUTO64K, - C_NSAUTO, - C_NPAUTO, - C_LAUTO, - C_PPOREG, - C_PSOREG, - C_UOREG4K, - C_UOREG8K, - C_UOREG16K, - C_UOREG32K, - C_UOREG64K, - C_NSOREG, - C_NPOREG, - C_LOREG, - C_LACON, - C_LCON, - C_VCON: - if a.Name == obj.NAME_EXTERN { - fmt.Printf("addpool: %v in %v needs reloc\n", DRconv(c), p) - } - - t.To.Type = obj.TYPE_CONST - t.To.Offset = lit - break - } - - for q := ctxt.Blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */ - if q.To == t.To { - p.Pcond = q - return - } - } - - q := ctxt.NewProg() - *q = t - q.Pc = int64(pool.size) - if ctxt.Blitrl == nil { - ctxt.Blitrl = q - pool.start = uint32(p.Pc) - } else { - ctxt.Elitrl.Link = q - } - ctxt.Elitrl = q - pool.size = -pool.size & (funcAlign - 1) - pool.size += uint32(sz) - p.Pcond = q -} - -func regoff(ctxt *obj.Link, a *obj.Addr) uint32 { - ctxt.Instoffset = 0 - aclass(ctxt, a) - return uint32(ctxt.Instoffset) -} - -// Maximum PC-relative displacement. -// The actual limit is ±2²⁰, but we are conservative -// to avoid needing to recompute the literal pool flush points -// as span-dependent jumps are enlarged. -const maxPCDisp = 512 * 1024 - -// ispcdisp reports whether v is a valid PC-relative displacement. -func ispcdisp(v int32) bool { - return -maxPCDisp < v && v < maxPCDisp && v&3 == 0 -} - -func isaddcon(v int64) bool { - /* uimm12 or uimm24? */ - if v < 0 { - return false - } - if (v & 0xFFF) == 0 { - v >>= 12 - } - return v <= 0xFFF -} - -// isbitcon returns whether a constant can be encoded into a logical instruction. -// bitcon has a binary form of repetition of a bit sequence of length 2, 4, 8, 16, 32, or 64, -// which itself is a rotate (w.r.t. the length of the unit) of a sequence of ones. -// special cases: 0 and -1 are not bitcon. -// this function needs to run against virtually all the constants, so it needs to be fast. -// for this reason, bitcon testing and bitcon encoding are separate functions. -func isbitcon(x uint64) bool { - if x == 1<<64-1 || x == 0 { - return false - } - // determine the period and sign-extend a unit to 64 bits - switch { - case x != x>>32|x<<32: - // period is 64 - // nothing to do - case x != x>>16|x<<48: - // period is 32 - x = uint64(int64(int32(x))) - case x != x>>8|x<<56: - // period is 16 - x = uint64(int64(int16(x))) - case x != x>>4|x<<60: - // period is 8 - x = uint64(int64(int8(x))) - default: - // period is 4 or 2, always true - // 0001, 0010, 0100, 1000 -- 0001 rotate - // 0011, 0110, 1100, 1001 -- 0011 rotate - // 0111, 1011, 1101, 1110 -- 0111 rotate - // 0101, 1010 -- 01 rotate, repeat - return true - } - return sequenceOfOnes(x) || sequenceOfOnes(^x) -} - -// sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros -func sequenceOfOnes(x uint64) bool { - y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2 - y += x - return (y-1)&y == 0 -} - -// bitconEncode returns the encoding of a bitcon used in logical instructions -// x is known to be a bitcon -// a bitcon is a sequence of n ones at low bits (i.e. 1<>32|x<<32: - period = 64 - case x != x>>16|x<<48: - period = 32 - x = uint64(int64(int32(x))) - case x != x>>8|x<<56: - period = 16 - x = uint64(int64(int16(x))) - case x != x>>4|x<<60: - period = 8 - x = uint64(int64(int8(x))) - case x != x>>2|x<<62: - period = 4 - x = uint64(int64(x<<60) >> 60) - default: - period = 2 - x = uint64(int64(x<<62) >> 62) - } - neg := false - if int64(x) < 0 { - x = ^x - neg = true - } - y := x & -x // lowest set bit of x. - s := log2(y) - n := log2(x+y) - s // x (or ^x) is a sequence of n ones left shifted by s bits - if neg { - // ^x is a sequence of n ones left shifted by s bits - // adjust n, s for x - s = n + s - n = period - n - } - - N := uint32(0) - if mode == 64 && period == 64 { - N = 1 - } - R := (period - s) & (period - 1) & uint32(mode-1) // shift amount of right rotate - S := (n - 1) | 63&^(period<<1-1) // low bits = #ones - 1, high bits encodes period - return N<<22 | R<<16 | S<<10 -} - -func log2(x uint64) uint32 { - if x == 0 { - panic("log2 of 0") - } - n := uint32(0) - if x >= 1<<32 { - x >>= 32 - n += 32 - } - if x >= 1<<16 { - x >>= 16 - n += 16 - } - if x >= 1<<8 { - x >>= 8 - n += 8 - } - if x >= 1<<4 { - x >>= 4 - n += 4 - } - if x >= 1<<2 { - x >>= 2 - n += 2 - } - if x >= 1<<1 { - x >>= 1 - n += 1 - } - return n -} - -func autoclass(l int64) int { - if l < 0 { - if l >= -256 { - return C_NSAUTO - } - if l >= -512 && (l&7) == 0 { - return C_NPAUTO - } - return C_LAUTO - } - - if l <= 255 { - return C_PSAUTO - } - if l <= 504 && (l&7) == 0 { - return C_PPAUTO - } - if l <= 4095 { - return C_UAUTO4K - } - if l <= 8190 && (l&1) == 0 { - return C_UAUTO8K - } - if l <= 16380 && (l&3) == 0 { - return C_UAUTO16K - } - if l <= 32760 && (l&7) == 0 { - return C_UAUTO32K - } - if l <= 65520 && (l&0xF) == 0 { - return C_UAUTO64K - } - return C_LAUTO -} - -func oregclass(l int64) int { - if l == 0 { - return C_ZOREG - } - return autoclass(l) - C_NPAUTO + C_NPOREG -} - -/* - * given an offset v and a class c (see above) - * return the offset value to use in the instruction, - * scaled if necessary - */ -func offsetshift(ctxt *obj.Link, v int64, c int) int64 { - s := 0 - if c >= C_SEXT1 && c <= C_SEXT16 { - s = c - C_SEXT1 - } else if c >= C_UAUTO4K && c <= C_UAUTO64K { - s = c - C_UAUTO4K - } else if c >= C_UOREG4K && c <= C_UOREG64K { - s = c - C_UOREG4K - } - vs := v >> uint(s) - if vs<= REG_SPECIAL: - return C_SPR - } - return C_GOK -} - -func aclass(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return C_NONE - - case obj.TYPE_REG: - return rclass(a.Reg) - - case obj.TYPE_REGREG: - return C_PAIR - - case obj.TYPE_SHIFT: - return C_SHIFT - - case obj.TYPE_MEM: - switch a.Name { - case obj.NAME_EXTERN, obj.NAME_STATIC: - if a.Sym == nil { - break - } - ctxt.Instoffset = a.Offset - if a.Sym != nil { // use relocation - if a.Sym.Type == obj.STLSBSS { - if ctxt.Flag_shared { - return C_TLS_IE - } else { - return C_TLS_LE - } - } - return C_ADDR - } - return C_LEXT - - case obj.NAME_GOTREF: - return C_GOTADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - return autoclass(ctxt.Instoffset) - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 - return autoclass(ctxt.Instoffset) - - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - return oregclass(ctxt.Instoffset) - } - return C_GOK - - case obj.TYPE_FCONST: - return C_FCON - - case obj.TYPE_TEXTSIZE: - return C_TEXTSIZE - - case obj.TYPE_CONST, obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if a.Reg != 0 && a.Reg != REGZERO { - goto aconsize - } - v := ctxt.Instoffset - if v == 0 { - return C_ZCON - } - if isaddcon(v) { - if v <= 0xFFF { - if isbitcon(uint64(v)) { - return C_ABCON0 - } - return C_ADDCON0 - } - if isbitcon(uint64(v)) { - return C_ABCON - } - return C_ADDCON - } - - t := movcon(v) - if t >= 0 { - if isbitcon(uint64(v)) { - return C_MBCON - } - return C_MOVCON - } - - t = movcon(^v) - if t >= 0 { - if isbitcon(uint64(v)) { - return C_MBCON - } - return C_MOVCON - } - - if isbitcon(uint64(v)) { - return C_BITCON - } - - if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) { - return C_LCON - } - return C_VCON - - case obj.NAME_EXTERN, obj.NAME_STATIC: - if a.Sym == nil { - break - } - if a.Sym.Type == obj.STLSBSS { - ctxt.Diag("taking address of TLS variable is not supported") - } - ctxt.Instoffset = a.Offset - return C_VCONADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - goto aconsize - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 - goto aconsize - } - return C_GOK - - aconsize: - if isaddcon(ctxt.Instoffset) { - return C_AACON - } - return C_LACON - - case obj.TYPE_BRANCH: - return C_SBRA - } - - return C_GOK -} - -func oclass(a *obj.Addr) int { - return int(a.Class) - 1 -} - -func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { - a1 := int(p.Optab) - if a1 != 0 { - return &optab[a1-1] - } - a1 = int(p.From.Class) - if a1 == 0 { - a1 = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(a1) - } - - a1-- - a3 := int(p.To.Class) - if a3 == 0 { - a3 = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(a3) - } - - a3-- - a2 := C_NONE - if p.Reg != 0 { - a2 = rclass(p.Reg) - } - - if false { - fmt.Printf("oplook %v %d %d %d\n", p.As, a1, a2, a3) - fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type) - } - - ops := oprange[p.As&obj.AMask] - c1 := &xcmp[a1] - c2 := &xcmp[a2] - c3 := &xcmp[a3] - c4 := &xcmp[p.Scond>>5] - for i := range ops { - op := &ops[i] - if (int(op.a2) == a2 || c2[op.a2]) && c4[op.scond>>5] && c1[op.a1] && c3[op.a3] { - p.Optab = uint16(cap(optab) - cap(ops) + i + 1) - return op - } - } - - ctxt.Diag("illegal combination %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type) - prasm(p) - if ops == nil { - ops = optab - } - return &ops[0] -} - -func cmp(a int, b int) bool { - if a == b { - return true - } - switch a { - case C_RSP: - if b == C_REG { - return true - } - - case C_REG: - if b == C_ZCON { - return true - } - - case C_ADDCON0: - if b == C_ZCON || b == C_ABCON0 { - return true - } - - case C_ADDCON: - if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON { - return true - } - - case C_BITCON: - if b == C_ABCON0 || b == C_ABCON || b == C_MBCON { - return true - } - - case C_MOVCON: - if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 { - return true - } - - case C_LCON: - if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON { - return true - } - - case C_VCON: - return cmp(C_LCON, b) - - case C_LACON: - if b == C_AACON { - return true - } - - case C_SEXT2: - if b == C_SEXT1 { - return true - } - - case C_SEXT4: - if b == C_SEXT1 || b == C_SEXT2 { - return true - } - - case C_SEXT8: - if b >= C_SEXT1 && b <= C_SEXT4 { - return true - } - - case C_SEXT16: - if b >= C_SEXT1 && b <= C_SEXT8 { - return true - } - - case C_LEXT: - if b >= C_SEXT1 && b <= C_SEXT16 { - return true - } - - case C_PPAUTO: - if b == C_PSAUTO { - return true - } - - case C_UAUTO4K: - if b == C_PSAUTO || b == C_PPAUTO { - return true - } - - case C_UAUTO8K: - return cmp(C_UAUTO4K, b) - - case C_UAUTO16K: - return cmp(C_UAUTO8K, b) - - case C_UAUTO32K: - return cmp(C_UAUTO16K, b) - - case C_UAUTO64K: - return cmp(C_UAUTO32K, b) - - case C_NPAUTO: - return cmp(C_NSAUTO, b) - - case C_LAUTO: - return cmp(C_NPAUTO, b) || cmp(C_UAUTO64K, b) - - case C_PSOREG: - if b == C_ZOREG { - return true - } - - case C_PPOREG: - if b == C_ZOREG || b == C_PSOREG { - return true - } - - case C_UOREG4K: - if b == C_ZOREG || b == C_PSAUTO || b == C_PSOREG || b == C_PPAUTO || b == C_PPOREG { - return true - } - - case C_UOREG8K: - return cmp(C_UOREG4K, b) - - case C_UOREG16K: - return cmp(C_UOREG8K, b) - - case C_UOREG32K: - return cmp(C_UOREG16K, b) - - case C_UOREG64K: - return cmp(C_UOREG32K, b) - - case C_NPOREG: - return cmp(C_NSOREG, b) - - case C_LOREG: - return cmp(C_NPOREG, b) || cmp(C_UOREG64K, b) - - case C_LBRA: - if b == C_SBRA { - return true - } - } - - return false -} - -type ocmp []Optab - -func (x ocmp) Len() int { - return len(x) -} - -func (x ocmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x ocmp) Less(i, j int) bool { - p1 := &x[i] - p2 := &x[j] - if p1.as != p2.as { - return p1.as < p2.as - } - if p1.a1 != p2.a1 { - return p1.a1 < p2.a1 - } - if p1.a2 != p2.a2 { - return p1.a2 < p2.a2 - } - if p1.a3 != p2.a3 { - return p1.a3 < p2.a3 - } - if p1.scond != p2.scond { - return p1.scond < p2.scond - } - return false -} - -func oprangeset(a obj.As, t []Optab) { - oprange[a&obj.AMask] = t -} - -func buildop(ctxt *obj.Link) { - var n int - for i := 0; i < C_GOK; i++ { - for n = 0; n < C_GOK; n++ { - if cmp(n, i) { - xcmp[i][n] = true - } - } - } - for n = 0; optab[n].as != obj.AXXX; n++ { - } - sort.Sort(ocmp(optab[:n])) - for i := 0; i < n; i++ { - r := optab[i].as - start := i - for optab[i].as == r { - i++ - } - t := optab[start:i] - i-- - oprangeset(r, t) - switch r { - default: - ctxt.Diag("unknown op in build: %v", r) - log.Fatalf("bad code") - - case AADD: - oprangeset(AADDS, t) - oprangeset(ASUB, t) - oprangeset(ASUBS, t) - oprangeset(AADDW, t) - oprangeset(AADDSW, t) - oprangeset(ASUBW, t) - oprangeset(ASUBSW, t) - - case AAND: /* logical immediate, logical shifted register */ - oprangeset(AANDS, t) - - oprangeset(AANDSW, t) - oprangeset(AANDW, t) - oprangeset(AEOR, t) - oprangeset(AEORW, t) - oprangeset(AORR, t) - oprangeset(AORRW, t) - - case ABIC: /* only logical shifted register */ - oprangeset(ABICS, t) - - oprangeset(ABICSW, t) - oprangeset(ABICW, t) - oprangeset(AEON, t) - oprangeset(AEONW, t) - oprangeset(AORN, t) - oprangeset(AORNW, t) - - case ANEG: - oprangeset(ANEGS, t) - oprangeset(ANEGSW, t) - oprangeset(ANEGW, t) - - case AADC: /* rn=Rd */ - oprangeset(AADCW, t) - - oprangeset(AADCS, t) - oprangeset(AADCSW, t) - oprangeset(ASBC, t) - oprangeset(ASBCW, t) - oprangeset(ASBCS, t) - oprangeset(ASBCSW, t) - - case ANGC: /* rn=REGZERO */ - oprangeset(ANGCW, t) - - oprangeset(ANGCS, t) - oprangeset(ANGCSW, t) - - case ACMP: - oprangeset(ACMPW, t) - oprangeset(ACMN, t) - oprangeset(ACMNW, t) - - case ATST: - oprangeset(ATSTW, t) - - /* register/register, and shifted */ - case AMVN: - oprangeset(AMVNW, t) - - case AMOVK: - oprangeset(AMOVKW, t) - oprangeset(AMOVN, t) - oprangeset(AMOVNW, t) - oprangeset(AMOVZ, t) - oprangeset(AMOVZW, t) - - case ABEQ: - oprangeset(ABNE, t) - oprangeset(ABCS, t) - oprangeset(ABHS, t) - oprangeset(ABCC, t) - oprangeset(ABLO, t) - oprangeset(ABMI, t) - oprangeset(ABPL, t) - oprangeset(ABVS, t) - oprangeset(ABVC, t) - oprangeset(ABHI, t) - oprangeset(ABLS, t) - oprangeset(ABGE, t) - oprangeset(ABLT, t) - oprangeset(ABGT, t) - oprangeset(ABLE, t) - - case ALSL: - oprangeset(ALSLW, t) - oprangeset(ALSR, t) - oprangeset(ALSRW, t) - oprangeset(AASR, t) - oprangeset(AASRW, t) - oprangeset(AROR, t) - oprangeset(ARORW, t) - - case ACLS: - oprangeset(ACLSW, t) - oprangeset(ACLZ, t) - oprangeset(ACLZW, t) - oprangeset(ARBIT, t) - oprangeset(ARBITW, t) - oprangeset(AREV, t) - oprangeset(AREVW, t) - oprangeset(AREV16, t) - oprangeset(AREV16W, t) - oprangeset(AREV32, t) - - case ASDIV: - oprangeset(ASDIVW, t) - oprangeset(AUDIV, t) - oprangeset(AUDIVW, t) - oprangeset(ACRC32B, t) - oprangeset(ACRC32CB, t) - oprangeset(ACRC32CH, t) - oprangeset(ACRC32CW, t) - oprangeset(ACRC32CX, t) - oprangeset(ACRC32H, t) - oprangeset(ACRC32W, t) - oprangeset(ACRC32X, t) - - case AMADD: - oprangeset(AMADDW, t) - oprangeset(AMSUB, t) - oprangeset(AMSUBW, t) - oprangeset(ASMADDL, t) - oprangeset(ASMSUBL, t) - oprangeset(AUMADDL, t) - oprangeset(AUMSUBL, t) - - case AREM: - oprangeset(AREMW, t) - oprangeset(AUREM, t) - oprangeset(AUREMW, t) - - case AMUL: - oprangeset(AMULW, t) - oprangeset(AMNEG, t) - oprangeset(AMNEGW, t) - oprangeset(ASMNEGL, t) - oprangeset(ASMULL, t) - oprangeset(ASMULH, t) - oprangeset(AUMNEGL, t) - oprangeset(AUMULH, t) - oprangeset(AUMULL, t) - - case AMOVB: - oprangeset(AMOVBU, t) - - case AMOVH: - oprangeset(AMOVHU, t) - - case AMOVW: - oprangeset(AMOVWU, t) - - case ABFM: - oprangeset(ABFMW, t) - oprangeset(ASBFM, t) - oprangeset(ASBFMW, t) - oprangeset(AUBFM, t) - oprangeset(AUBFMW, t) - - case ABFI: - oprangeset(ABFIW, t) - oprangeset(ABFXIL, t) - oprangeset(ABFXILW, t) - oprangeset(ASBFIZ, t) - oprangeset(ASBFIZW, t) - oprangeset(ASBFX, t) - oprangeset(ASBFXW, t) - oprangeset(AUBFIZ, t) - oprangeset(AUBFIZW, t) - oprangeset(AUBFX, t) - oprangeset(AUBFXW, t) - - case AEXTR: - oprangeset(AEXTRW, t) - - case ASXTB: - oprangeset(ASXTBW, t) - oprangeset(ASXTH, t) - oprangeset(ASXTHW, t) - oprangeset(ASXTW, t) - oprangeset(AUXTB, t) - oprangeset(AUXTH, t) - oprangeset(AUXTW, t) - oprangeset(AUXTBW, t) - oprangeset(AUXTHW, t) - - case ACCMN: - oprangeset(ACCMNW, t) - oprangeset(ACCMP, t) - oprangeset(ACCMPW, t) - - case ACSEL: - oprangeset(ACSELW, t) - oprangeset(ACSINC, t) - oprangeset(ACSINCW, t) - oprangeset(ACSINV, t) - oprangeset(ACSINVW, t) - oprangeset(ACSNEG, t) - oprangeset(ACSNEGW, t) - - // aliases Rm=Rn, !cond - oprangeset(ACINC, t) - - oprangeset(ACINCW, t) - oprangeset(ACINV, t) - oprangeset(ACINVW, t) - oprangeset(ACNEG, t) - oprangeset(ACNEGW, t) - - // aliases, Rm=Rn=REGZERO, !cond - case ACSET: - oprangeset(ACSETW, t) - - oprangeset(ACSETM, t) - oprangeset(ACSETMW, t) - - case AMOVD, - AMOVBU, - AB, - ABL, - AWORD, - ADWORD, - obj.ARET, - obj.ATEXT, - ASTP, - ALDP: - break - - case AERET: - oprangeset(AWFE, t) - oprangeset(AWFI, t) - oprangeset(AYIELD, t) - oprangeset(ASEV, t) - oprangeset(ASEVL, t) - oprangeset(ADRPS, t) - - case ACBZ: - oprangeset(ACBZW, t) - oprangeset(ACBNZ, t) - oprangeset(ACBNZW, t) - - case ATBZ: - oprangeset(ATBNZ, t) - - case AADR, AADRP: - break - - case ACLREX: - break - - case ASVC: - oprangeset(AHLT, t) - oprangeset(AHVC, t) - oprangeset(ASMC, t) - oprangeset(ABRK, t) - oprangeset(ADCPS1, t) - oprangeset(ADCPS2, t) - oprangeset(ADCPS3, t) - - case AFADDS: - oprangeset(AFADDD, t) - oprangeset(AFSUBS, t) - oprangeset(AFSUBD, t) - oprangeset(AFMULS, t) - oprangeset(AFMULD, t) - oprangeset(AFNMULS, t) - oprangeset(AFNMULD, t) - oprangeset(AFDIVS, t) - oprangeset(AFMAXD, t) - oprangeset(AFMAXS, t) - oprangeset(AFMIND, t) - oprangeset(AFMINS, t) - oprangeset(AFMAXNMD, t) - oprangeset(AFMAXNMS, t) - oprangeset(AFMINNMD, t) - oprangeset(AFMINNMS, t) - oprangeset(AFDIVD, t) - - case AFCVTSD: - oprangeset(AFCVTDS, t) - oprangeset(AFABSD, t) - oprangeset(AFABSS, t) - oprangeset(AFNEGD, t) - oprangeset(AFNEGS, t) - oprangeset(AFSQRTD, t) - oprangeset(AFSQRTS, t) - oprangeset(AFRINTNS, t) - oprangeset(AFRINTND, t) - oprangeset(AFRINTPS, t) - oprangeset(AFRINTPD, t) - oprangeset(AFRINTMS, t) - oprangeset(AFRINTMD, t) - oprangeset(AFRINTZS, t) - oprangeset(AFRINTZD, t) - oprangeset(AFRINTAS, t) - oprangeset(AFRINTAD, t) - oprangeset(AFRINTXS, t) - oprangeset(AFRINTXD, t) - oprangeset(AFRINTIS, t) - oprangeset(AFRINTID, t) - oprangeset(AFCVTDH, t) - oprangeset(AFCVTHS, t) - oprangeset(AFCVTHD, t) - oprangeset(AFCVTSH, t) - - case AFCMPS: - oprangeset(AFCMPD, t) - oprangeset(AFCMPES, t) - oprangeset(AFCMPED, t) - - case AFCCMPS: - oprangeset(AFCCMPD, t) - oprangeset(AFCCMPES, t) - oprangeset(AFCCMPED, t) - - case AFCSELD: - oprangeset(AFCSELS, t) - - case AFMOVS, AFMOVD: - break - - case AFCVTZSD: - oprangeset(AFCVTZSDW, t) - oprangeset(AFCVTZSS, t) - oprangeset(AFCVTZSSW, t) - oprangeset(AFCVTZUD, t) - oprangeset(AFCVTZUDW, t) - oprangeset(AFCVTZUS, t) - oprangeset(AFCVTZUSW, t) - - case ASCVTFD: - oprangeset(ASCVTFS, t) - oprangeset(ASCVTFWD, t) - oprangeset(ASCVTFWS, t) - oprangeset(AUCVTFD, t) - oprangeset(AUCVTFS, t) - oprangeset(AUCVTFWD, t) - oprangeset(AUCVTFWS, t) - - case ASYS: - oprangeset(AAT, t) - oprangeset(ADC, t) - oprangeset(AIC, t) - oprangeset(ATLBI, t) - - case ASYSL, AHINT: - break - - case ADMB: - oprangeset(ADSB, t) - oprangeset(AISB, t) - - case AMRS, AMSR: - break - - case ALDAR: - oprangeset(ALDARW, t) - fallthrough - - case ALDXR: - oprangeset(ALDXRB, t) - oprangeset(ALDXRH, t) - oprangeset(ALDXRW, t) - - case ALDAXR: - oprangeset(ALDAXRB, t) - oprangeset(ALDAXRH, t) - oprangeset(ALDAXRW, t) - - case ALDXP: - oprangeset(ALDXPW, t) - - case ASTLR: - oprangeset(ASTLRW, t) - - case ASTXR: - oprangeset(ASTXRB, t) - oprangeset(ASTXRH, t) - oprangeset(ASTXRW, t) - - case ASTLXR: - oprangeset(ASTLXRB, t) - oprangeset(ASTLXRH, t) - oprangeset(ASTLXRW, t) - - case ASTXP: - oprangeset(ASTXPW, t) - - case AAESD: - oprangeset(AAESE, t) - oprangeset(AAESMC, t) - oprangeset(AAESIMC, t) - oprangeset(ASHA1H, t) - oprangeset(ASHA1SU1, t) - oprangeset(ASHA256SU0, t) - - case ASHA1C: - oprangeset(ASHA1P, t) - oprangeset(ASHA1M, t) - oprangeset(ASHA1SU0, t) - oprangeset(ASHA256H, t) - oprangeset(ASHA256H2, t) - oprangeset(ASHA256SU1, t) - - case obj.ANOP, - obj.AUNDEF, - obj.AUSEFIELD, - obj.AFUNCDATA, - obj.APCDATA, - obj.ADUFFZERO, - obj.ADUFFCOPY: - break - } - } -} - -func chipfloat7(ctxt *obj.Link, e float64) int { - ei := math.Float64bits(e) - l := uint32(int32(ei)) - h := uint32(int32(ei >> 32)) - - if l != 0 || h&0xffff != 0 { - return -1 - } - h1 := h & 0x7fc00000 - if h1 != 0x40000000 && h1 != 0x3fc00000 { - return -1 - } - n := 0 - - // sign bit (a) - if h&0x80000000 != 0 { - n |= 1 << 7 - } - - // exp sign bit (b) - if h1 == 0x3fc00000 { - n |= 1 << 6 - } - - // rest of exp and mantissa (cd-efgh) - n |= int((h >> 16) & 0x3f) - - //print("match %.8lux %.8lux %d\n", l, h, n); - return n -} - -/* form offset parameter to SYS; special register number */ -func SYSARG5(op0 int, op1 int, Cn int, Cm int, op2 int) int { - return op0<<19 | op1<<16 | Cn<<12 | Cm<<8 | op2<<5 -} - -func SYSARG4(op1 int, Cn int, Cm int, op2 int) int { - return SYSARG5(0, op1, Cn, Cm, op2) -} - -func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { - o1 := uint32(0) - o2 := uint32(0) - o3 := uint32(0) - o4 := uint32(0) - o5 := uint32(0) - if false { /*debug['P']*/ - fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_) - } - switch o.type_ { - default: - ctxt.Diag("unknown asm %d", o.type_) - prasm(p) - - case 0: /* pseudo ops */ - break - - case 1: /* op Rm,[Rn],Rd; default Rn=Rd -> op Rm<<0,[Rn,]Rd (shifted register) */ - o1 = oprrr(ctxt, p.As) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - r := int(p.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = REGZERO - } - if r == 0 { - r = rt - } - o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) - - case 2: /* add/sub $(uimm12|uimm24)[,R],R; cmp $(uimm12|uimm24),R */ - o1 = opirr(ctxt, p.As) - - rt := int(p.To.Reg) - if p.To.Type == obj.TYPE_NONE { - if (o1 & Sbit) == 0 { - ctxt.Diag("ineffective ZR destination\n%v", p) - } - rt = REGZERO - } - - r := int(p.Reg) - if r == 0 { - r = rt - } - v := int32(regoff(ctxt, &p.From)) - o1 = oaddi(ctxt, int32(o1), v, r, rt) - - case 3: /* op R<>= 12 - o1 |= 1 << 22 /* shift, by 12 */ - } - - o1 |= ((uint32(v) & 0xFFF) << 10) | (uint32(r&31) << 5) | uint32(rt&31) - - case 5: /* b s; bl s */ - o1 = opbra(ctxt, p.As) - - if p.To.Sym == nil { - o1 |= uint32(brdist(ctxt, p, 0, 26, 2)) - break - } - - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - rel.Type = obj.R_CALLARM64 - - case 6: /* b ,O(R); bl ,O(R) */ - o1 = opbrr(ctxt, p.As) - - o1 |= uint32(p.To.Reg&31) << 5 - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 0 - rel.Type = obj.R_CALLIND - - case 7: /* beq s */ - o1 = opbra(ctxt, p.As) - - o1 |= uint32(brdist(ctxt, p, 0, 19, 2) << 5) - - case 8: /* lsl $c,[R],R -> ubfm $(W-1)-c,$(-c MOD (W-1)),Rn,Rd */ - rt := int(p.To.Reg) - - rf := int(p.Reg) - if rf == 0 { - rf = rt - } - v := int32(p.From.Offset) - switch p.As { - case AASR: - o1 = opbfm(ctxt, ASBFM, int(v), 63, rf, rt) - - case AASRW: - o1 = opbfm(ctxt, ASBFMW, int(v), 31, rf, rt) - - case ALSL: - o1 = opbfm(ctxt, AUBFM, int((64-v)&63), int(63-v), rf, rt) - - case ALSLW: - o1 = opbfm(ctxt, AUBFMW, int((32-v)&31), int(31-v), rf, rt) - - case ALSR: - o1 = opbfm(ctxt, AUBFM, int(v), 63, rf, rt) - - case ALSRW: - o1 = opbfm(ctxt, AUBFMW, int(v), 31, rf, rt) - - case AROR: - o1 = opextr(ctxt, AEXTR, v, rf, rf, rt) - - case ARORW: - o1 = opextr(ctxt, AEXTRW, v, rf, rf, rt) - - default: - ctxt.Diag("bad shift $con\n%v", ctxt.Curp) - break - } - - case 9: /* lsl Rm,[Rn],Rd -> lslv Rm, Rn, Rd */ - o1 = oprrr(ctxt, p.As) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 |= (uint32(p.From.Reg&31) << 16) | (uint32(r&31) << 5) | uint32(p.To.Reg&31) - - case 10: /* brk/hvc/.../svc [$con] */ - o1 = opimm(ctxt, p.As) - - if p.To.Type != obj.TYPE_NONE { - o1 |= uint32((p.To.Offset & 0xffff) << 5) - } - - case 11: /* dword */ - aclass(ctxt, &p.To) - - o1 = uint32(ctxt.Instoffset) - o2 = uint32(ctxt.Instoffset >> 32) - if p.To.Sym != nil { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - rel.Type = obj.R_ADDR - o2 = 0 - o1 = o2 - } - - case 12: /* movT $vcon, reg */ - o1 = omovlit(ctxt, p.As, p, &p.From, int(p.To.Reg)) - - case 13: /* addop $vcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */ - o1 = omovlit(ctxt, AMOVD, p, &p.From, REGTMP) - - if !(o1 != 0) { - break - } - rt := int(p.To.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = REGZERO - } - r := int(p.Reg) - if r == 0 { - r = rt - } - if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) { - o2 = opxrrr(ctxt, p.As) - o2 |= REGTMP & 31 << 16 - o2 |= LSL0_64 - } else { - o2 = oprrr(ctxt, p.As) - o2 |= REGTMP & 31 << 16 /* shift is 0 */ - } - - o2 |= uint32(r&31) << 5 - o2 |= uint32(rt & 31) - - case 14: /* word */ - if aclass(ctxt, &p.To) == C_ADDR { - ctxt.Diag("address constant needs DWORD\n%v", p) - } - o1 = uint32(ctxt.Instoffset) - if p.To.Sym != nil { - // This case happens with words generated - // in the PC stream as part of the literal pool. - rel := obj.Addrel(ctxt.Cursym) - - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - rel.Type = obj.R_ADDR - o1 = 0 - } - - case 15: /* mul/mneg/umulh/umull r,[r,]r; madd/msub Rm,Rn,Ra,Rd */ - o1 = oprrr(ctxt, p.As) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - var r int - var ra int - if p.From3Type() == obj.TYPE_REG { - r = int(p.From3.Reg) - ra = int(p.Reg) - if ra == 0 { - ra = REGZERO - } - } else { - r = int(p.Reg) - if r == 0 { - r = rt - } - ra = REGZERO - } - - o1 |= (uint32(rf&31) << 16) | (uint32(ra&31) << 10) | (uint32(r&31) << 5) | uint32(rt&31) - - case 16: /* XremY R[,R],R -> XdivY; XmsubY */ - o1 = oprrr(ctxt, p.As) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - r := int(p.Reg) - if r == 0 { - r = rt - } - o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | REGTMP&31 - o2 = oprrr(ctxt, AMSUBW) - o2 |= o1 & (1 << 31) /* same size */ - o2 |= (uint32(rf&31) << 16) | (uint32(r&31) << 10) | (REGTMP & 31 << 5) | uint32(rt&31) - - case 17: /* op Rm,[Rn],Rd; default Rn=ZR */ - o1 = oprrr(ctxt, p.As) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - r := int(p.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = REGZERO - } - if r == 0 { - r = REGZERO - } - o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) - - case 18: /* csel cond,Rn,Rm,Rd; cinc/cinv/cneg cond,Rn,Rd; cset cond,Rd */ - o1 = oprrr(ctxt, p.As) - - cond := int(p.From.Reg) - r := int(p.Reg) - var rf int - if r != 0 { - if p.From3Type() == obj.TYPE_NONE { - /* CINC/CINV/CNEG */ - rf = r - - cond ^= 1 - } else { - rf = int(p.From3.Reg) /* CSEL */ - } - } else { - /* CSET */ - if p.From3Type() != obj.TYPE_NONE { - ctxt.Diag("invalid combination\n%v", p) - } - rf = REGZERO - r = rf - cond ^= 1 - } - - rt := int(p.To.Reg) - o1 |= (uint32(rf&31) << 16) | (uint32(cond&31) << 12) | (uint32(r&31) << 5) | uint32(rt&31) - - case 19: /* CCMN cond, (Rm|uimm5),Rn, uimm4 -> ccmn Rn,Rm,uimm4,cond */ - nzcv := int(p.To.Offset) - - cond := int(p.From.Reg) - var rf int - if p.From3.Type == obj.TYPE_REG { - o1 = oprrr(ctxt, p.As) - rf = int(p.From3.Reg) /* Rm */ - } else { - o1 = opirr(ctxt, p.As) - rf = int(p.From3.Offset & 0x1F) - } - - o1 |= (uint32(rf&31) << 16) | (uint32(cond) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv) - - case 20: /* movT R,O(R) -> strT */ - v := int32(regoff(ctxt, &p.To)) - sz := int32(1 << uint(movesize(p.As))) - - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */ - o1 = olsr9s(ctxt, int32(opstr9(ctxt, p.As)), v, r, int(p.From.Reg)) - } else { - v = int32(offsetshift(ctxt, int64(v), int(o.a3))) - o1 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), v, r, int(p.From.Reg)) - } - - case 21: /* movT O(R),R -> ldrT */ - v := int32(regoff(ctxt, &p.From)) - sz := int32(1 << uint(movesize(p.As))) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */ - o1 = olsr9s(ctxt, int32(opldr9(ctxt, p.As)), v, r, int(p.To.Reg)) - } else { - v = int32(offsetshift(ctxt, int64(v), int(o.a1))) - //print("offset=%lld v=%ld a1=%d\n", instoffset, v, o->a1); - o1 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), v, r, int(p.To.Reg)) - } - - case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */ - v := int32(p.From.Offset) - - if v < -256 || v > 255 { - ctxt.Diag("offset out of range\n%v", p) - } - o1 = opldrpp(ctxt, p.As) - if o.scond == C_XPOST { - o1 |= 1 << 10 - } else { - o1 |= 3 << 10 - } - o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31) - - case 23: /* movT R,(R)O!; movT O(R)!, R -> strT */ - v := int32(p.To.Offset) - - if v < -256 || v > 255 { - ctxt.Diag("offset out of range\n%v", p) - } - o1 = LD2STR(opldrpp(ctxt, p.As)) - if o.scond == C_XPOST { - o1 |= 1 << 10 - } else { - o1 |= 3 << 10 - } - o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.To.Reg&31) << 5) | uint32(p.From.Reg&31) - - case 24: /* mov/mvn Rs,Rd -> add $0,Rs,Rd or orr Rs,ZR,Rd */ - rf := int(p.From.Reg) - rt := int(p.To.Reg) - s := rf == REGSP || rt == REGSP - if p.As == AMVN || p.As == AMVNW { - if s { - ctxt.Diag("illegal SP reference\n%v", p) - } - o1 = oprrr(ctxt, p.As) - o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) - } else if s { - o1 = opirr(ctxt, p.As) - o1 |= (uint32(rf&31) << 5) | uint32(rt&31) - } else { - o1 = oprrr(ctxt, p.As) - o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) - } - - case 25: /* negX Rs, Rd -> subX Rs<<0, ZR, Rd */ - o1 = oprrr(ctxt, p.As) - - rf := int(p.From.Reg) - if rf == C_NONE { - rf = int(p.To.Reg) - } - rt := int(p.To.Reg) - o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) - - case 26: /* negX Rm< subX Rm< strT */ - s := movesize(o.as) - - if s < 0 { - ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p) - } - v := int32(regoff(ctxt, &p.To)) - if v < 0 { - ctxt.Diag("negative large offset\n%v", p) - } - if (v & ((1 << uint(s)) - 1)) != 0 { - ctxt.Diag("misaligned offset\n%v", p) - } - hi := v - (v & (0xFFF << uint(s))) - if (hi & 0xFFF) != 0 { - ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p) - } - - //fprint(2, "v=%ld (%#lux) s=%d hi=%ld (%#lux) v'=%ld (%#lux)\n", v, v, s, hi, hi, ((v-hi)>>s)&0xFFF, ((v-hi)>>s)&0xFFF); - r := int(p.To.Reg) - - if r == 0 { - r = int(o.param) - } - o1 = oaddi(ctxt, int32(opirr(ctxt, AADD)), hi, r, REGTMP) - o2 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg)) - - case 31: /* movT L(R), R -> ldrT */ - s := movesize(o.as) - - if s < 0 { - ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p) - } - v := int32(regoff(ctxt, &p.From)) - if v < 0 { - ctxt.Diag("negative large offset\n%v", p) - } - if (v & ((1 << uint(s)) - 1)) != 0 { - ctxt.Diag("misaligned offset\n%v", p) - } - hi := v - (v & (0xFFF << uint(s))) - if (hi & 0xFFF) != 0 { - ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p) - } - - //fprint(2, "v=%ld (%#lux) s=%d hi=%ld (%#lux) v'=%ld (%#lux)\n", v, v, s, hi, hi, ((v-hi)>>s)&0xFFF, ((v-hi)>>s)&0xFFF); - r := int(p.From.Reg) - - if r == 0 { - r = int(o.param) - } - o1 = oaddi(ctxt, int32(opirr(ctxt, AADD)), hi, r, REGTMP) - o2 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg)) - - case 32: /* mov $con, R -> movz/movn */ - o1 = omovconst(ctxt, p.As, p, &p.From, int(p.To.Reg)) - - case 33: /* movk $uimm16 << pos */ - o1 = opirr(ctxt, p.As) - - d := p.From.Offset - if (d >> 16) != 0 { - ctxt.Diag("requires uimm16\n%v", p) - } - s := 0 - if p.From3Type() != obj.TYPE_NONE { - if p.From3.Type != obj.TYPE_CONST { - ctxt.Diag("missing bit position\n%v", p) - } - s = int(p.From3.Offset / 16) - if (s*16&0xF) != 0 || s >= 4 || (o1&S64) == 0 && s >= 2 { - ctxt.Diag("illegal bit position\n%v", p) - } - } - - rt := int(p.To.Reg) - o1 |= uint32(((d & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31)) - - case 34: /* mov $lacon,R */ - o1 = omovlit(ctxt, AMOVD, p, &p.From, REGTMP) - - if !(o1 != 0) { - break - } - o2 = opxrrr(ctxt, AADD) - o2 |= REGTMP & 31 << 16 - o2 |= LSL0_64 - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 |= uint32(r&31) << 5 - o2 |= uint32(p.To.Reg & 31) - - case 35: /* mov SPR,R -> mrs */ - o1 = oprrr(ctxt, AMRS) - - v := int32(p.From.Offset) - if (o1 & uint32(v&^(3<<19))) != 0 { - ctxt.Diag("MRS register value overlap\n%v", p) - } - o1 |= uint32(v) - o1 |= uint32(p.To.Reg & 31) - - case 36: /* mov R,SPR */ - o1 = oprrr(ctxt, AMSR) - - v := int32(p.To.Offset) - if (o1 & uint32(v&^(3<<19))) != 0 { - ctxt.Diag("MSR register value overlap\n%v", p) - } - o1 |= uint32(v) - o1 |= uint32(p.From.Reg & 31) - - case 37: /* mov $con,PSTATEfield -> MSR [immediate] */ - if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 { - ctxt.Diag("illegal immediate for PSTATE field\n%v", p) - } - o1 = opirr(ctxt, AMSR) - o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */ - v := int32(0) - for i := 0; i < len(pstatefield); i++ { - if int64(pstatefield[i].a) == p.To.Offset { - v = int32(pstatefield[i].b) - break - } - } - - if v == 0 { - ctxt.Diag("illegal PSTATE field for immediate move\n%v", p) - } - o1 |= uint32(v) - - case 38: /* clrex [$imm] */ - o1 = opimm(ctxt, p.As) - - if p.To.Type == obj.TYPE_NONE { - o1 |= 0xF << 8 - } else { - o1 |= uint32((p.To.Offset & 0xF) << 8) - } - - case 39: /* cbz R, rel */ - o1 = opirr(ctxt, p.As) - - o1 |= uint32(p.From.Reg & 31) - o1 |= uint32(brdist(ctxt, p, 0, 19, 2) << 5) - - case 40: /* tbz */ - o1 = opirr(ctxt, p.As) - - v := int32(p.From.Offset) - if v < 0 || v > 63 { - ctxt.Diag("illegal bit number\n%v", p) - } - o1 |= ((uint32(v) & 0x20) << (31 - 5)) | ((uint32(v) & 0x1F) << 19) - o1 |= uint32(brdist(ctxt, p, 0, 14, 2) << 5) - o1 |= uint32(p.Reg) - - case 41: /* eret, nop, others with no operands */ - o1 = op0(ctxt, p.As) - - case 42: /* bfm R,r,s,R */ - o1 = opbfm(ctxt, p.As, int(p.From.Offset), int(p.From3.Offset), int(p.Reg), int(p.To.Reg)) - - case 43: /* bfm aliases */ - r := int(p.From.Offset) - - s := int(p.From3.Offset) - rf := int(p.Reg) - rt := int(p.To.Reg) - if rf == 0 { - rf = rt - } - switch p.As { - case ABFI: - o1 = opbfm(ctxt, ABFM, 64-r, s-1, rf, rt) - - case ABFIW: - o1 = opbfm(ctxt, ABFMW, 32-r, s-1, rf, rt) - - case ABFXIL: - o1 = opbfm(ctxt, ABFM, r, r+s-1, rf, rt) - - case ABFXILW: - o1 = opbfm(ctxt, ABFMW, r, r+s-1, rf, rt) - - case ASBFIZ: - o1 = opbfm(ctxt, ASBFM, 64-r, s-1, rf, rt) - - case ASBFIZW: - o1 = opbfm(ctxt, ASBFMW, 32-r, s-1, rf, rt) - - case ASBFX: - o1 = opbfm(ctxt, ASBFM, r, r+s-1, rf, rt) - - case ASBFXW: - o1 = opbfm(ctxt, ASBFMW, r, r+s-1, rf, rt) - - case AUBFIZ: - o1 = opbfm(ctxt, AUBFM, 64-r, s-1, rf, rt) - - case AUBFIZW: - o1 = opbfm(ctxt, AUBFMW, 32-r, s-1, rf, rt) - - case AUBFX: - o1 = opbfm(ctxt, AUBFM, r, r+s-1, rf, rt) - - case AUBFXW: - o1 = opbfm(ctxt, AUBFMW, r, r+s-1, rf, rt) - - default: - ctxt.Diag("bad bfm alias\n%v", ctxt.Curp) - break - } - - case 44: /* extr $b, Rn, Rm, Rd */ - o1 = opextr(ctxt, p.As, int32(p.From.Offset), int(p.From3.Reg), int(p.Reg), int(p.To.Reg)) - - case 45: /* sxt/uxt[bhw] R,R; movT R,R -> sxtT R,R */ - rf := int(p.From.Reg) - - rt := int(p.To.Reg) - as := p.As - if rf == REGZERO { - as = AMOVWU /* clearer in disassembly */ - } - switch as { - case AMOVB, ASXTB: - o1 = opbfm(ctxt, ASBFM, 0, 7, rf, rt) - - case AMOVH, ASXTH: - o1 = opbfm(ctxt, ASBFM, 0, 15, rf, rt) - - case AMOVW, ASXTW: - o1 = opbfm(ctxt, ASBFM, 0, 31, rf, rt) - - case AMOVBU, AUXTB: - o1 = opbfm(ctxt, AUBFM, 0, 7, rf, rt) - - case AMOVHU, AUXTH: - o1 = opbfm(ctxt, AUBFM, 0, 15, rf, rt) - - case AMOVWU: - o1 = oprrr(ctxt, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) - - case AUXTW: - o1 = opbfm(ctxt, AUBFM, 0, 31, rf, rt) - - case ASXTBW: - o1 = opbfm(ctxt, ASBFMW, 0, 7, rf, rt) - - case ASXTHW: - o1 = opbfm(ctxt, ASBFMW, 0, 15, rf, rt) - - case AUXTBW: - o1 = opbfm(ctxt, AUBFMW, 0, 7, rf, rt) - - case AUXTHW: - o1 = opbfm(ctxt, AUBFMW, 0, 15, rf, rt) - - default: - ctxt.Diag("bad sxt %v", as) - break - } - - case 46: /* cls */ - o1 = opbit(ctxt, p.As) - - o1 |= uint32(p.From.Reg&31) << 5 - o1 |= uint32(p.To.Reg & 31) - - case 47: /* movT R,V(R) -> strT (huge offset) */ - o1 = omovlit(ctxt, AMOVW, p, &p.To, REGTMP) - - if !(o1 != 0) { - break - } - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o2 = olsxrr(ctxt, p.As, REGTMP, r, int(p.From.Reg)) - - case 48: /* movT V(R), R -> ldrT (huge offset) */ - o1 = omovlit(ctxt, AMOVW, p, &p.From, REGTMP) - - if !(o1 != 0) { - break - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 = olsxrr(ctxt, p.As, REGTMP, r, int(p.To.Reg)) - - case 50: /* sys/sysl */ - o1 = opirr(ctxt, p.As) - - if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 { - ctxt.Diag("illegal SYS argument\n%v", p) - } - o1 |= uint32(p.From.Offset) - if p.To.Type == obj.TYPE_REG { - o1 |= uint32(p.To.Reg & 31) - } else if p.Reg != 0 { - o1 |= uint32(p.Reg & 31) - } else { - o1 |= 0x1F - } - - case 51: /* dmb */ - o1 = opirr(ctxt, p.As) - - if p.From.Type == obj.TYPE_CONST { - o1 |= uint32((p.From.Offset & 0xF) << 8) - } - - case 52: /* hint */ - o1 = opirr(ctxt, p.As) - - o1 |= uint32((p.From.Offset & 0x7F) << 5) - - case 53: /* and/or/eor/bic/... $bitcon, Rn, Rd */ - a := p.As - rt := int(p.To.Reg) - r := int(p.Reg) - if r == 0 { - r = rt - } - mode := 64 - v := uint64(p.From.Offset) - switch p.As { - case AANDW, AORRW, AEORW, AANDSW: - mode = 32 - case ABIC, AORN, AEON, ABICS: - v = ^v - case ABICW, AORNW, AEONW, ABICSW: - v = ^v - mode = 32 - } - o1 = opirr(ctxt, a) - o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31) - - case 54: /* floating point arith */ - o1 = oprrr(ctxt, p.As) - - var rf int - if p.From.Type == obj.TYPE_CONST { - rf = chipfloat7(ctxt, p.From.Val.(float64)) - if rf < 0 || true { - ctxt.Diag("invalid floating-point immediate\n%v", p) - rf = 0 - } - - rf |= (1 << 3) - } else { - rf = int(p.From.Reg) - } - rt := int(p.To.Reg) - r := int(p.Reg) - if (o1&(0x1F<<24)) == (0x1E<<24) && (o1&(1<<11)) == 0 { /* monadic */ - r = rf - rf = 0 - } else if r == 0 { - r = rt - } - o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) - - case 56: /* floating point compare */ - o1 = oprrr(ctxt, p.As) - - var rf int - if p.From.Type == obj.TYPE_CONST { - o1 |= 8 /* zero */ - rf = 0 - } else { - rf = int(p.From.Reg) - } - rt := int(p.Reg) - o1 |= uint32(rf&31)<<16 | uint32(rt&31)<<5 - - case 57: /* floating point conditional compare */ - o1 = oprrr(ctxt, p.As) - - cond := int(p.From.Reg) - nzcv := int(p.To.Offset) - if nzcv&^0xF != 0 { - ctxt.Diag("implausible condition\n%v", p) - } - rf := int(p.Reg) - if p.From3 == nil || p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 { - ctxt.Diag("illegal FCCMP\n%v", p) - break - } - rt := int(p.From3.Reg) - o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv) - - case 58: /* ldar/ldxr/ldaxr */ - o1 = opload(ctxt, p.As) - - o1 |= 0x1F << 16 - o1 |= uint32(p.From.Reg) << 5 - if p.Reg != 0 { - o1 |= uint32(p.Reg) << 10 - } else { - o1 |= 0x1F << 10 - } - o1 |= uint32(p.To.Reg & 31) - - case 59: /* stxr/stlxr */ - o1 = opstore(ctxt, p.As) - - if p.RegTo2 != obj.REG_NONE { - o1 |= uint32(p.RegTo2&31) << 16 - } else { - o1 |= 0x1F << 16 - } - - // TODO(aram): add support for STXP - o1 |= uint32(p.To.Reg&31) << 5 - - o1 |= uint32(p.From.Reg & 31) - - case 60: /* adrp label,r */ - d := brdist(ctxt, p, 12, 21, 0) - - o1 = ADR(1, uint32(d), uint32(p.To.Reg)) - - case 61: /* adr label, r */ - d := brdist(ctxt, p, 0, 21, 0) - - o1 = ADR(0, uint32(d), uint32(p.To.Reg)) - - case 62: /* op $movcon, [R], R -> mov $movcon, REGTMP + op REGTMP, [R], R */ - if p.Reg == REGTMP { - ctxt.Diag("cannot use REGTMP as source: %v\n", p) - } - o1 = omovconst(ctxt, AMOVD, p, &p.From, REGTMP) - - rt := int(p.To.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = REGZERO - } - r := int(p.Reg) - if r == 0 { - r = rt - } - if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) { - o2 = opxrrr(ctxt, p.As) - o2 |= REGTMP & 31 << 16 - o2 |= LSL0_64 - } else { - o2 = oprrr(ctxt, p.As) - o2 |= REGTMP & 31 << 16 /* shift is 0 */ - } - o2 |= uint32(r&31) << 5 - o2 |= uint32(rt & 31) - - /* reloc ops */ - case 64: /* movT R,addr -> adrp + add + movT R, (REGTMP) */ - o1 = ADR(1, 0, REGTMP) - o2 = opirr(ctxt, AADD) | REGTMP&31<<5 | REGTMP&31 - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - rel.Type = obj.R_ADDRARM64 - o3 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), 0, REGTMP, int(p.From.Reg)) - - case 65: /* movT addr,R -> adrp + add + movT (REGTMP), R */ - o1 = ADR(1, 0, REGTMP) - o2 = opirr(ctxt, AADD) | REGTMP&31<<5 | REGTMP&31 - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDRARM64 - o3 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), 0, REGTMP, int(p.To.Reg)) - - case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */ - v := int32(p.From.Offset) - - if v < -512 || v > 504 { - ctxt.Diag("offset out of range\n%v", p) - } - if o.scond == C_XPOST { - o1 |= 1 << 23 - } else { - o1 |= 3 << 23 - } - o1 |= 1 << 22 - o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.To.Offset<<10 | int64(uint32(p.From.Reg&31)<<5) | int64(p.To.Reg&31)) - - case 67: /* stp (r1, r2), O(R)!; stp (r1, r2), (R)O! */ - v := int32(p.To.Offset) - - if v < -512 || v > 504 { - ctxt.Diag("offset out of range\n%v", p) - } - if o.scond == C_XPOST { - o1 |= 1 << 23 - } else { - o1 |= 3 << 23 - } - o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.From.Offset<<10 | int64(uint32(p.To.Reg&31)<<5) | int64(p.From.Reg&31)) - - case 68: /* movT $vconaddr(SB), reg -> adrp + add + reloc */ - if p.As == AMOVW { - ctxt.Diag("invalid load of 32-bit address: %v", p) - } - o1 = ADR(1, 0, uint32(p.To.Reg)) - o2 = opirr(ctxt, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDRARM64 - - case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */ - o1 = opirr(ctxt, AMOVZ) - o1 |= uint32(p.To.Reg & 31) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Type = obj.R_ARM64_TLS_LE - if p.From.Offset != 0 { - ctxt.Diag("invalid offset on MOVW $tlsvar") - } - - case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */ - o1 = ADR(1, 0, REGTMP) - o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Add = 0 - rel.Type = obj.R_ARM64_TLS_IE - if p.From.Offset != 0 { - ctxt.Diag("invalid offset on MOVW $tlsvar") - } - - case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */ - o1 = ADR(1, 0, REGTMP) - o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Add = 0 - rel.Type = obj.R_ARM64_GOTPCREL - - // This is supposed to be something that stops execution. - // It's not supposed to be reached, ever, but if it is, we'd - // like to be able to tell how we got there. Assemble as - // 0xbea71700 which is guaranteed to raise undefined instruction - // exception. - case 90: - o1 = 0xbea71700 - - break - } - - out[0] = o1 - out[1] = o2 - out[2] = o3 - out[3] = o4 - out[4] = o5 - return -} - -/* - * basic Rm op Rn -> Rd (using shifted register with 0) - * also op Rn -> Rt - * also Rm*Rn op Ra -> Rd - */ -func oprrr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AADC: - return S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10 - - case AADCW: - return S32 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10 - - case AADCS: - return S64 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10 - - case AADCSW: - return S32 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10 - - case ANGC, ASBC: - return S64 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10 - - case ANGCS, ASBCS: - return S64 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10 - - case ANGCW, ASBCW: - return S32 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10 - - case ANGCSW, ASBCSW: - return S32 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10 - - case AADD: - return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case AADDW: - return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case ACMN, AADDS: - return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case ACMNW, AADDSW: - return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case ASUB: - return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case ASUBW: - return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case ACMP, ASUBS: - return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case ACMPW, ASUBSW: - return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10 - - case AAND: - return S64 | 0<<29 | 0xA<<24 - - case AANDW: - return S32 | 0<<29 | 0xA<<24 - - case AMOVD, AORR: - return S64 | 1<<29 | 0xA<<24 - - // case AMOVW: - case AMOVWU, AORRW: - return S32 | 1<<29 | 0xA<<24 - - case AEOR: - return S64 | 2<<29 | 0xA<<24 - - case AEORW: - return S32 | 2<<29 | 0xA<<24 - - case AANDS: - return S64 | 3<<29 | 0xA<<24 - - case AANDSW: - return S32 | 3<<29 | 0xA<<24 - - case ABIC: - return S64 | 0<<29 | 0xA<<24 | 1<<21 - - case ABICW: - return S32 | 0<<29 | 0xA<<24 | 1<<21 - - case ABICS: - return S64 | 3<<29 | 0xA<<24 | 1<<21 - - case ABICSW: - return S32 | 3<<29 | 0xA<<24 | 1<<21 - - case AEON: - return S64 | 2<<29 | 0xA<<24 | 1<<21 - - case AEONW: - return S32 | 2<<29 | 0xA<<24 | 1<<21 - - case AMVN, AORN: - return S64 | 1<<29 | 0xA<<24 | 1<<21 - - case AMVNW, AORNW: - return S32 | 1<<29 | 0xA<<24 | 1<<21 - - case AASR: - return S64 | OPDP2(10) /* also ASRV */ - - case AASRW: - return S32 | OPDP2(10) - - case ALSL: - return S64 | OPDP2(8) - - case ALSLW: - return S32 | OPDP2(8) - - case ALSR: - return S64 | OPDP2(9) - - case ALSRW: - return S32 | OPDP2(9) - - case AROR: - return S64 | OPDP2(11) - - case ARORW: - return S32 | OPDP2(11) - - case ACCMN: - return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* cond<<12 | nzcv<<0 */ - - case ACCMNW: - return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 - - case ACCMP: - return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */ - - case ACCMPW: - return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 - - case ACRC32B: - return S32 | OPDP2(16) - - case ACRC32H: - return S32 | OPDP2(17) - - case ACRC32W: - return S32 | OPDP2(18) - - case ACRC32X: - return S64 | OPDP2(19) - - case ACRC32CB: - return S32 | OPDP2(20) - - case ACRC32CH: - return S32 | OPDP2(21) - - case ACRC32CW: - return S32 | OPDP2(22) - - case ACRC32CX: - return S64 | OPDP2(23) - - case ACSEL: - return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 - - case ACSELW: - return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 - - case ACSET: - return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 - - case ACSETW: - return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 - - case ACSETM: - return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 - - case ACSETMW: - return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 - - case ACINC, ACSINC: - return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 - - case ACINCW, ACSINCW: - return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 - - case ACINV, ACSINV: - return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 - - case ACINVW, ACSINVW: - return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10 - - case ACNEG, ACSNEG: - return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 - - case ACNEGW, ACSNEGW: - return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10 - - case AMUL, AMADD: - return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15 - - case AMULW, AMADDW: - return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15 - - case AMNEG, AMSUB: - return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15 - - case AMNEGW, AMSUBW: - return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15 - - case AMRS: - return SYSOP(1, 2, 0, 0, 0, 0, 0) - - case AMSR: - return SYSOP(0, 2, 0, 0, 0, 0, 0) - - case ANEG: - return S64 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21 - - case ANEGW: - return S32 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21 - - case ANEGS: - return S64 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21 - - case ANEGSW: - return S32 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21 - - case AREM, ASDIV: - return S64 | OPDP2(3) - - case AREMW, ASDIVW: - return S32 | OPDP2(3) - - case ASMULL, ASMADDL: - return OPDP3(1, 0, 1, 0) - - case ASMNEGL, ASMSUBL: - return OPDP3(1, 0, 1, 1) - - case ASMULH: - return OPDP3(1, 0, 2, 0) - - case AUMULL, AUMADDL: - return OPDP3(1, 0, 5, 0) - - case AUMNEGL, AUMSUBL: - return OPDP3(1, 0, 5, 1) - - case AUMULH: - return OPDP3(1, 0, 6, 0) - - case AUREM, AUDIV: - return S64 | OPDP2(2) - - case AUREMW, AUDIVW: - return S32 | OPDP2(2) - - case AAESE: - return 0x4E<<24 | 2<<20 | 8<<16 | 4<<12 | 2<<10 - - case AAESD: - return 0x4E<<24 | 2<<20 | 8<<16 | 5<<12 | 2<<10 - - case AAESMC: - return 0x4E<<24 | 2<<20 | 8<<16 | 6<<12 | 2<<10 - - case AAESIMC: - return 0x4E<<24 | 2<<20 | 8<<16 | 7<<12 | 2<<10 - - case ASHA1C: - return 0x5E<<24 | 0<<12 - - case ASHA1P: - return 0x5E<<24 | 1<<12 - - case ASHA1M: - return 0x5E<<24 | 2<<12 - - case ASHA1SU0: - return 0x5E<<24 | 3<<12 - - case ASHA256H: - return 0x5E<<24 | 4<<12 - - case ASHA256H2: - return 0x5E<<24 | 5<<12 - - case ASHA256SU1: - return 0x5E<<24 | 6<<12 - - case ASHA1H: - return 0x5E<<24 | 2<<20 | 8<<16 | 0<<12 | 2<<10 - - case ASHA1SU1: - return 0x5E<<24 | 2<<20 | 8<<16 | 1<<12 | 2<<10 - - case ASHA256SU0: - return 0x5E<<24 | 2<<20 | 8<<16 | 2<<12 | 2<<10 - - case AFCVTZSD: - return FPCVTI(1, 0, 1, 3, 0) - - case AFCVTZSDW: - return FPCVTI(0, 0, 1, 3, 0) - - case AFCVTZSS: - return FPCVTI(1, 0, 0, 3, 0) - - case AFCVTZSSW: - return FPCVTI(0, 0, 0, 3, 0) - - case AFCVTZUD: - return FPCVTI(1, 0, 1, 3, 1) - - case AFCVTZUDW: - return FPCVTI(0, 0, 1, 3, 1) - - case AFCVTZUS: - return FPCVTI(1, 0, 0, 3, 1) - - case AFCVTZUSW: - return FPCVTI(0, 0, 0, 3, 1) - - case ASCVTFD: - return FPCVTI(1, 0, 1, 0, 2) - - case ASCVTFS: - return FPCVTI(1, 0, 0, 0, 2) - - case ASCVTFWD: - return FPCVTI(0, 0, 1, 0, 2) - - case ASCVTFWS: - return FPCVTI(0, 0, 0, 0, 2) - - case AUCVTFD: - return FPCVTI(1, 0, 1, 0, 3) - - case AUCVTFS: - return FPCVTI(1, 0, 0, 0, 3) - - case AUCVTFWD: - return FPCVTI(0, 0, 1, 0, 3) - - case AUCVTFWS: - return FPCVTI(0, 0, 0, 0, 3) - - case AFADDS: - return FPOP2S(0, 0, 0, 2) - - case AFADDD: - return FPOP2S(0, 0, 1, 2) - - case AFSUBS: - return FPOP2S(0, 0, 0, 3) - - case AFSUBD: - return FPOP2S(0, 0, 1, 3) - - case AFMULS: - return FPOP2S(0, 0, 0, 0) - - case AFMULD: - return FPOP2S(0, 0, 1, 0) - - case AFDIVS: - return FPOP2S(0, 0, 0, 1) - - case AFDIVD: - return FPOP2S(0, 0, 1, 1) - - case AFMAXS: - return FPOP2S(0, 0, 0, 4) - - case AFMINS: - return FPOP2S(0, 0, 0, 5) - - case AFMAXD: - return FPOP2S(0, 0, 1, 4) - - case AFMIND: - return FPOP2S(0, 0, 1, 5) - - case AFMAXNMS: - return FPOP2S(0, 0, 0, 6) - - case AFMAXNMD: - return FPOP2S(0, 0, 1, 6) - - case AFMINNMS: - return FPOP2S(0, 0, 0, 7) - - case AFMINNMD: - return FPOP2S(0, 0, 1, 7) - - case AFNMULS: - return FPOP2S(0, 0, 0, 8) - - case AFNMULD: - return FPOP2S(0, 0, 1, 8) - - case AFCMPS: - return FPCMP(0, 0, 0, 0, 0) - - case AFCMPD: - return FPCMP(0, 0, 1, 0, 0) - - case AFCMPES: - return FPCMP(0, 0, 0, 0, 16) - - case AFCMPED: - return FPCMP(0, 0, 1, 0, 16) - - case AFCCMPS: - return FPCCMP(0, 0, 0, 0) - - case AFCCMPD: - return FPCCMP(0, 0, 1, 0) - - case AFCCMPES: - return FPCCMP(0, 0, 0, 1) - - case AFCCMPED: - return FPCCMP(0, 0, 1, 1) - - case AFCSELS: - return 0x1E<<24 | 0<<22 | 1<<21 | 3<<10 - - case AFCSELD: - return 0x1E<<24 | 1<<22 | 1<<21 | 3<<10 - - case AFMOVS: - return FPOP1S(0, 0, 0, 0) - - case AFABSS: - return FPOP1S(0, 0, 0, 1) - - case AFNEGS: - return FPOP1S(0, 0, 0, 2) - - case AFSQRTS: - return FPOP1S(0, 0, 0, 3) - - case AFCVTSD: - return FPOP1S(0, 0, 0, 5) - - case AFCVTSH: - return FPOP1S(0, 0, 0, 7) - - case AFRINTNS: - return FPOP1S(0, 0, 0, 8) - - case AFRINTPS: - return FPOP1S(0, 0, 0, 9) - - case AFRINTMS: - return FPOP1S(0, 0, 0, 10) - - case AFRINTZS: - return FPOP1S(0, 0, 0, 11) - - case AFRINTAS: - return FPOP1S(0, 0, 0, 12) - - case AFRINTXS: - return FPOP1S(0, 0, 0, 14) - - case AFRINTIS: - return FPOP1S(0, 0, 0, 15) - - case AFMOVD: - return FPOP1S(0, 0, 1, 0) - - case AFABSD: - return FPOP1S(0, 0, 1, 1) - - case AFNEGD: - return FPOP1S(0, 0, 1, 2) - - case AFSQRTD: - return FPOP1S(0, 0, 1, 3) - - case AFCVTDS: - return FPOP1S(0, 0, 1, 4) - - case AFCVTDH: - return FPOP1S(0, 0, 1, 7) - - case AFRINTND: - return FPOP1S(0, 0, 1, 8) - - case AFRINTPD: - return FPOP1S(0, 0, 1, 9) - - case AFRINTMD: - return FPOP1S(0, 0, 1, 10) - - case AFRINTZD: - return FPOP1S(0, 0, 1, 11) - - case AFRINTAD: - return FPOP1S(0, 0, 1, 12) - - case AFRINTXD: - return FPOP1S(0, 0, 1, 14) - - case AFRINTID: - return FPOP1S(0, 0, 1, 15) - - case AFCVTHS: - return FPOP1S(0, 0, 3, 4) - - case AFCVTHD: - return FPOP1S(0, 0, 3, 5) - } - - ctxt.Diag("bad rrr %d %v", a, a) - prasm(ctxt.Curp) - return 0 -} - -/* - * imm -> Rd - * imm op Rn -> Rd - */ -func opirr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - /* op $addcon, Rn, Rd */ - case AMOVD, AADD: - return S64 | 0<<30 | 0<<29 | 0x11<<24 - - case ACMN, AADDS: - return S64 | 0<<30 | 1<<29 | 0x11<<24 - - case AMOVW, AADDW: - return S32 | 0<<30 | 0<<29 | 0x11<<24 - - case ACMNW, AADDSW: - return S32 | 0<<30 | 1<<29 | 0x11<<24 - - case ASUB: - return S64 | 1<<30 | 0<<29 | 0x11<<24 - - case ACMP, ASUBS: - return S64 | 1<<30 | 1<<29 | 0x11<<24 - - case ASUBW: - return S32 | 1<<30 | 0<<29 | 0x11<<24 - - case ACMPW, ASUBSW: - return S32 | 1<<30 | 1<<29 | 0x11<<24 - - /* op $imm(SB), Rd; op label, Rd */ - case AADR: - return 0<<31 | 0x10<<24 - - case AADRP: - return 1<<31 | 0x10<<24 - - /* op $bimm, Rn, Rd */ - case AAND, ABIC: - return S64 | 0<<29 | 0x24<<23 - - case AANDW, ABICW: - return S32 | 0<<29 | 0x24<<23 | 0<<22 - - case AORR, AORN: - return S64 | 1<<29 | 0x24<<23 - - case AORRW, AORNW: - return S32 | 1<<29 | 0x24<<23 | 0<<22 - - case AEOR, AEON: - return S64 | 2<<29 | 0x24<<23 - - case AEORW, AEONW: - return S32 | 2<<29 | 0x24<<23 | 0<<22 - - case AANDS, ABICS: - return S64 | 3<<29 | 0x24<<23 - - case AANDSW, ABICSW: - return S32 | 3<<29 | 0x24<<23 | 0<<22 - - case AASR: - return S64 | 0<<29 | 0x26<<23 /* alias of SBFM */ - - case AASRW: - return S32 | 0<<29 | 0x26<<23 | 0<<22 - - /* op $width, $lsb, Rn, Rd */ - case ABFI: - return S64 | 2<<29 | 0x26<<23 | 1<<22 - /* alias of BFM */ - - case ABFIW: - return S32 | 2<<29 | 0x26<<23 | 0<<22 - - /* op $imms, $immr, Rn, Rd */ - case ABFM: - return S64 | 1<<29 | 0x26<<23 | 1<<22 - - case ABFMW: - return S32 | 1<<29 | 0x26<<23 | 0<<22 - - case ASBFM: - return S64 | 0<<29 | 0x26<<23 | 1<<22 - - case ASBFMW: - return S32 | 0<<29 | 0x26<<23 | 0<<22 - - case AUBFM: - return S64 | 2<<29 | 0x26<<23 | 1<<22 - - case AUBFMW: - return S32 | 2<<29 | 0x26<<23 | 0<<22 - - case ABFXIL: - return S64 | 1<<29 | 0x26<<23 | 1<<22 /* alias of BFM */ - - case ABFXILW: - return S32 | 1<<29 | 0x26<<23 | 0<<22 - - case AEXTR: - return S64 | 0<<29 | 0x27<<23 | 1<<22 | 0<<21 - - case AEXTRW: - return S32 | 0<<29 | 0x27<<23 | 0<<22 | 0<<21 - - case ACBNZ: - return S64 | 0x1A<<25 | 1<<24 - - case ACBNZW: - return S32 | 0x1A<<25 | 1<<24 - - case ACBZ: - return S64 | 0x1A<<25 | 0<<24 - - case ACBZW: - return S32 | 0x1A<<25 | 0<<24 - - case ACCMN: - return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */ - - case ACCMNW: - return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 - - case ACCMP: - return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */ - - case ACCMPW: - return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 - - case AMOVK: - return S64 | 3<<29 | 0x25<<23 - - case AMOVKW: - return S32 | 3<<29 | 0x25<<23 - - case AMOVN: - return S64 | 0<<29 | 0x25<<23 - - case AMOVNW: - return S32 | 0<<29 | 0x25<<23 - - case AMOVZ: - return S64 | 2<<29 | 0x25<<23 - - case AMOVZW: - return S32 | 2<<29 | 0x25<<23 - - case AMSR: - return SYSOP(0, 0, 0, 4, 0, 0, 0x1F) /* MSR (immediate) */ - - case AAT, - ADC, - AIC, - ATLBI, - ASYS: - return SYSOP(0, 1, 0, 0, 0, 0, 0) - - case ASYSL: - return SYSOP(1, 1, 0, 0, 0, 0, 0) - - case ATBZ: - return 0x36 << 24 - - case ATBNZ: - return 0x37 << 24 - - case ADSB: - return SYSOP(0, 0, 3, 3, 0, 4, 0x1F) - - case ADMB: - return SYSOP(0, 0, 3, 3, 0, 5, 0x1F) - - case AISB: - return SYSOP(0, 0, 3, 3, 0, 6, 0x1F) - - case AHINT: - return SYSOP(0, 0, 3, 2, 0, 0, 0x1F) - } - - ctxt.Diag("bad irr %v", a) - prasm(ctxt.Curp) - return 0 -} - -func opbit(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ACLS: - return S64 | OPBIT(5) - - case ACLSW: - return S32 | OPBIT(5) - - case ACLZ: - return S64 | OPBIT(4) - - case ACLZW: - return S32 | OPBIT(4) - - case ARBIT: - return S64 | OPBIT(0) - - case ARBITW: - return S32 | OPBIT(0) - - case AREV: - return S64 | OPBIT(3) - - case AREVW: - return S32 | OPBIT(2) - - case AREV16: - return S64 | OPBIT(1) - - case AREV16W: - return S32 | OPBIT(1) - - case AREV32: - return S64 | OPBIT(2) - - default: - ctxt.Diag("bad bit op\n%v", ctxt.Curp) - return 0 - } -} - -/* - * add/subtract extended register - */ -func opxrrr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AADD: - return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64 - - case AADDW: - return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32 - - case ACMN, AADDS: - return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64 - - case ACMNW, AADDSW: - return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32 - - case ASUB: - return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64 - - case ASUBW: - return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32 - - case ACMP, ASUBS: - return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64 - - case ACMPW, ASUBSW: - return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32 - } - - ctxt.Diag("bad opxrrr %v\n%v", a, ctxt.Curp) - return 0 -} - -func opimm(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ASVC: - return 0xD4<<24 | 0<<21 | 1 /* imm16<<5 */ - - case AHVC: - return 0xD4<<24 | 0<<21 | 2 - - case ASMC: - return 0xD4<<24 | 0<<21 | 3 - - case ABRK: - return 0xD4<<24 | 1<<21 | 0 - - case AHLT: - return 0xD4<<24 | 2<<21 | 0 - - case ADCPS1: - return 0xD4<<24 | 5<<21 | 1 - - case ADCPS2: - return 0xD4<<24 | 5<<21 | 2 - - case ADCPS3: - return 0xD4<<24 | 5<<21 | 3 - - case ACLREX: - return SYSOP(0, 0, 3, 3, 0, 2, 0x1F) - } - - ctxt.Diag("bad imm %v", a) - prasm(ctxt.Curp) - return 0 -} - -func brdist(ctxt *obj.Link, p *obj.Prog, preshift int, flen int, shift int) int64 { - v := int64(0) - t := int64(0) - if p.Pcond != nil { - v = (p.Pcond.Pc >> uint(preshift)) - (ctxt.Pc >> uint(preshift)) - if (v & ((1 << uint(shift)) - 1)) != 0 { - ctxt.Diag("misaligned label\n%v", p) - } - v >>= uint(shift) - t = int64(1) << uint(flen-1) - if v < -t || v >= t { - ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, ctxt.Blitrl, p, p.Pcond) - panic("branch too far") - } - } - - return v & ((t << 1) - 1) -} - -/* - * pc-relative branches - */ -func opbra(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ABEQ: - return OPBcc(0x0) - - case ABNE: - return OPBcc(0x1) - - case ABCS: - return OPBcc(0x2) - - case ABHS: - return OPBcc(0x2) - - case ABCC: - return OPBcc(0x3) - - case ABLO: - return OPBcc(0x3) - - case ABMI: - return OPBcc(0x4) - - case ABPL: - return OPBcc(0x5) - - case ABVS: - return OPBcc(0x6) - - case ABVC: - return OPBcc(0x7) - - case ABHI: - return OPBcc(0x8) - - case ABLS: - return OPBcc(0x9) - - case ABGE: - return OPBcc(0xa) - - case ABLT: - return OPBcc(0xb) - - case ABGT: - return OPBcc(0xc) - - case ABLE: - return OPBcc(0xd) /* imm19<<5 | cond */ - - case AB: - return 0<<31 | 5<<26 /* imm26 */ - - case obj.ADUFFZERO, obj.ADUFFCOPY, ABL: - return 1<<31 | 5<<26 - } - - ctxt.Diag("bad bra %v", a) - prasm(ctxt.Curp) - return 0 -} - -func opbrr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ABL: - return OPBLR(1) /* BLR */ - - case AB: - return OPBLR(0) /* BR */ - - case obj.ARET: - return OPBLR(2) /* RET */ - } - - ctxt.Diag("bad brr %v", a) - prasm(ctxt.Curp) - return 0 -} - -func op0(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ADRPS: - return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5 - - case AERET: - return 0x6B<<25 | 4<<21 | 0x1F<<16 | 0<<10 | 0x1F<<5 - - // case ANOP: - // return SYSHINT(0) - - case AYIELD: - return SYSHINT(1) - - case AWFE: - return SYSHINT(2) - - case AWFI: - return SYSHINT(3) - - case ASEV: - return SYSHINT(4) - - case ASEVL: - return SYSHINT(5) - } - - ctxt.Diag("bad op0 %v", a) - prasm(ctxt.Curp) - return 0 -} - -/* - * register offset - */ -func opload(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ALDAR: - return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10 - - case ALDARW: - return LDSTX(2, 1, 1, 0, 1) | 0x1F<<10 - - case ALDARB: - return LDSTX(0, 1, 1, 0, 1) | 0x1F<<10 - - case ALDARH: - return LDSTX(1, 1, 1, 0, 1) | 0x1F<<10 - - case ALDAXP: - return LDSTX(3, 0, 1, 1, 1) - - case ALDAXPW: - return LDSTX(2, 0, 1, 1, 1) - - case ALDAXR: - return LDSTX(3, 0, 1, 0, 1) | 0x1F<<10 - - case ALDAXRW: - return LDSTX(2, 0, 1, 0, 1) | 0x1F<<10 - - case ALDAXRB: - return LDSTX(0, 0, 1, 0, 1) | 0x1F<<10 - - case ALDAXRH: - return LDSTX(1, 0, 1, 0, 1) | 0x1F<<10 - - case ALDXR: - return LDSTX(3, 0, 1, 0, 0) | 0x1F<<10 - - case ALDXRB: - return LDSTX(0, 0, 1, 0, 0) | 0x1F<<10 - - case ALDXRH: - return LDSTX(1, 0, 1, 0, 0) | 0x1F<<10 - - case ALDXRW: - return LDSTX(2, 0, 1, 0, 0) | 0x1F<<10 - - case ALDXP: - return LDSTX(3, 0, 1, 1, 0) - - case ALDXPW: - return LDSTX(2, 0, 1, 1, 0) - - case AMOVNP: - return S64 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22 - - case AMOVNPW: - return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22 - } - - ctxt.Diag("bad opload %v\n%v", a, ctxt.Curp) - return 0 -} - -func opstore(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ASTLR: - return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10 - - case ASTLRB: - return LDSTX(0, 1, 0, 0, 1) | 0x1F<<10 - - case ASTLRH: - return LDSTX(1, 1, 0, 0, 1) | 0x1F<<10 - - case ASTLP: - return LDSTX(3, 0, 0, 1, 1) - - case ASTLPW: - return LDSTX(2, 0, 0, 1, 1) - - case ASTLRW: - return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10 - - case ASTLXP: - return LDSTX(2, 0, 0, 1, 1) - - case ASTLXPW: - return LDSTX(3, 0, 0, 1, 1) - - case ASTLXR: - return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10 - - case ASTLXRB: - return LDSTX(0, 0, 0, 0, 1) | 0x1F<<10 - - case ASTLXRH: - return LDSTX(1, 0, 0, 0, 1) | 0x1F<<10 - - case ASTLXRW: - return LDSTX(2, 0, 0, 0, 1) | 0x1F<<10 - - case ASTXR: - return LDSTX(3, 0, 0, 0, 0) | 0x1F<<10 - - case ASTXRB: - return LDSTX(0, 0, 0, 0, 0) | 0x1F<<10 - - case ASTXRH: - return LDSTX(1, 0, 0, 0, 0) | 0x1F<<10 - - case ASTXP: - return LDSTX(3, 0, 0, 1, 0) - - case ASTXPW: - return LDSTX(2, 0, 0, 1, 0) - - case ASTXRW: - return LDSTX(2, 0, 0, 0, 0) | 0x1F<<10 - - case AMOVNP: - return S64 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22 - - case AMOVNPW: - return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22 - } - - ctxt.Diag("bad opstore %v\n%v", a, ctxt.Curp) - return 0 -} - -/* - * load/store register (unsigned immediate) C3.3.13 - * these produce 64-bit values (when there's an option) - */ -func olsr12u(ctxt *obj.Link, o int32, v int32, b int, r int) uint32 { - if v < 0 || v >= (1<<12) { - ctxt.Diag("offset out of range: %d\n%v", v, ctxt.Curp) - } - o |= (v & 0xFFF) << 10 - o |= int32(b&31) << 5 - o |= int32(r & 31) - return uint32(o) -} - -func opldr12(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVD: - return LDSTR12U(3, 0, 1) /* imm12<<10 | Rn<<5 | Rt */ - - case AMOVW: - return LDSTR12U(2, 0, 2) - - case AMOVWU: - return LDSTR12U(2, 0, 1) - - case AMOVH: - return LDSTR12U(1, 0, 2) - - case AMOVHU: - return LDSTR12U(1, 0, 1) - - case AMOVB: - return LDSTR12U(0, 0, 2) - - case AMOVBU: - return LDSTR12U(0, 0, 1) - - case AFMOVS: - return LDSTR12U(2, 1, 1) - - case AFMOVD: - return LDSTR12U(3, 1, 1) - } - - ctxt.Diag("bad opldr12 %v\n%v", a, ctxt.Curp) - return 0 -} - -func opstr12(ctxt *obj.Link, a obj.As) uint32 { - return LD2STR(opldr12(ctxt, a)) -} - -/* - * load/store register (unscaled immediate) C3.3.12 - */ -func olsr9s(ctxt *obj.Link, o int32, v int32, b int, r int) uint32 { - if v < -256 || v > 255 { - ctxt.Diag("offset out of range: %d\n%v", v, ctxt.Curp) - } - o |= (v & 0x1FF) << 12 - o |= int32(b&31) << 5 - o |= int32(r & 31) - return uint32(o) -} - -func opldr9(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVD: - return LDSTR9S(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */ - - case AMOVW: - return LDSTR9S(2, 0, 2) - - case AMOVWU: - return LDSTR9S(2, 0, 1) - - case AMOVH: - return LDSTR9S(1, 0, 2) - - case AMOVHU: - return LDSTR9S(1, 0, 1) - - case AMOVB: - return LDSTR9S(0, 0, 2) - - case AMOVBU: - return LDSTR9S(0, 0, 1) - - case AFMOVS: - return LDSTR9S(2, 1, 1) - - case AFMOVD: - return LDSTR9S(3, 1, 1) - } - - ctxt.Diag("bad opldr9 %v\n%v", a, ctxt.Curp) - return 0 -} - -func opstr9(ctxt *obj.Link, a obj.As) uint32 { - return LD2STR(opldr9(ctxt, a)) -} - -func opldrpp(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVD: - return 3<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 /* simm9<<12 | Rn<<5 | Rt */ - - case AMOVW: - return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22 - - case AMOVWU: - return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 - - case AMOVH: - return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22 - - case AMOVHU: - return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 - - case AMOVB: - return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22 - - case AMOVBU: - return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 - } - - ctxt.Diag("bad opldr %v\n%v", a, ctxt.Curp) - return 0 -} - -/* - * load/store register (extended register) - */ -func olsxrr(ctxt *obj.Link, as obj.As, rt int, r1 int, r2 int) uint32 { - ctxt.Diag("need load/store extended register\n%v", ctxt.Curp) - return 0xffffffff -} - -func oaddi(ctxt *obj.Link, o1 int32, v int32, r int, rt int) uint32 { - if (v & 0xFFF000) != 0 { - if v&0xFFF != 0 { - ctxt.Diag("%v misuses oaddi", ctxt.Curp) - } - v >>= 12 - o1 |= 1 << 22 - } - - o1 |= ((v & 0xFFF) << 10) | (int32(r&31) << 5) | int32(rt&31) - return uint32(o1) -} - -/* - * load a a literal value into dr - */ -func omovlit(ctxt *obj.Link, as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 { - var o1 int32 - if p.Pcond == nil { /* not in literal pool */ - aclass(ctxt, a) - ctxt.Logf("omovlit add %d (%#x)\n", ctxt.Instoffset, uint64(ctxt.Instoffset)) - - /* TODO: could be clever, and use general constant builder */ - o1 = int32(opirr(ctxt, AADD)) - - v := int32(ctxt.Instoffset) - if v != 0 && (v&0xFFF) == 0 { - v >>= 12 - o1 |= 1 << 22 /* shift, by 12 */ - } - - o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31) - } else { - fp := 0 - w := 0 /* default: 32 bit, unsigned */ - switch as { - case AFMOVS: - fp = 1 - - case AFMOVD: - fp = 1 - w = 1 /* 64 bit simd&fp */ - - case AMOVD: - if p.Pcond.As == ADWORD { - w = 1 /* 64 bit */ - } else if p.Pcond.To.Offset < 0 { - w = 2 /* sign extend */ - } - - case AMOVB, AMOVH, AMOVW: - w = 2 /* 32 bit, sign-extended to 64 */ - break - } - - v := int32(brdist(ctxt, p, 0, 19, 2)) - o1 = (int32(w) << 30) | (int32(fp) << 26) | (3 << 27) - o1 |= (v & 0x7FFFF) << 5 - o1 |= int32(dr & 31) - } - - return uint32(o1) -} - -// load a constant (MOVCON or BITCON) in a into rt -func omovconst(ctxt *obj.Link, as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint32) { - if c := oclass(a); c == C_BITCON || c == C_ABCON || c == C_ABCON0 { - // or $bitcon, REGZERO, rt - mode := 64 - var as1 obj.As - switch as { - case AMOVW: - as1 = AORRW - mode = 32 - case AMOVD: - as1 = AORR - } - o1 = opirr(ctxt, as1) - o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31) - return o1 - } - - r := 32 - if as == AMOVD { - r = 64 - } - d := a.Offset - s := movcon(d) - if s < 0 || s >= r { - d = ^d - s = movcon(d) - if s < 0 || s >= r { - ctxt.Diag("impossible move wide: %#x\n%v", uint64(a.Offset), p) - } - if as == AMOVD { - o1 = opirr(ctxt, AMOVN) - } else { - o1 = opirr(ctxt, AMOVNW) - } - } else { - if as == AMOVD { - o1 = opirr(ctxt, AMOVZ) - } else { - o1 = opirr(ctxt, AMOVZW) - } - } - o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31)) - return o1 -} - -func opbfm(ctxt *obj.Link, a obj.As, r int, s int, rf int, rt int) uint32 { - var c uint32 - o := opirr(ctxt, a) - if (o & (1 << 31)) == 0 { - c = 32 - } else { - c = 64 - } - if r < 0 || uint32(r) >= c { - ctxt.Diag("illegal bit number\n%v", ctxt.Curp) - } - o |= (uint32(r) & 0x3F) << 16 - if s < 0 || uint32(s) >= c { - ctxt.Diag("illegal bit number\n%v", ctxt.Curp) - } - o |= (uint32(s) & 0x3F) << 10 - o |= (uint32(rf&31) << 5) | uint32(rt&31) - return o -} - -func opextr(ctxt *obj.Link, a obj.As, v int32, rn int, rm int, rt int) uint32 { - var c uint32 - o := opirr(ctxt, a) - if (o & (1 << 31)) != 0 { - c = 63 - } else { - c = 31 - } - if v < 0 || uint32(v) > c { - ctxt.Diag("illegal bit number\n%v", ctxt.Curp) - } - o |= uint32(v) << 10 - o |= uint32(rn&31) << 5 - o |= uint32(rm&31) << 16 - o |= uint32(rt & 31) - return o -} - -/* - * size in log2(bytes) - */ -func movesize(a obj.As) int { - switch a { - case AMOVD: - return 3 - - case AMOVW, AMOVWU: - return 2 - - case AMOVH, AMOVHU: - return 1 - - case AMOVB, AMOVBU: - return 0 - - case AFMOVS: - return 2 - - case AFMOVD: - return 3 - - default: - return -1 - } -} diff --git a/vendor/github.com/google/gops/internal/obj/arm64/list7.go b/vendor/github.com/google/gops/internal/obj/arm64/list7.go deleted file mode 100644 index 01971b85..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm64/list7.go +++ /dev/null @@ -1,115 +0,0 @@ -// cmd/7l/list.c and cmd/7l/sub.c from Vita Nuova. -// https://code.google.com/p/ken-cc/source/browse/ -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm64 - -import ( - "fmt" - - "github.com/google/gops/internal/obj" -) - -var strcond = [16]string{ - "EQ", - "NE", - "HS", - "LO", - "MI", - "PL", - "VS", - "VC", - "HI", - "LS", - "GE", - "LT", - "GT", - "LE", - "AL", - "NV", -} - -func init() { - obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, Rconv) - obj.RegisterOpcode(obj.ABaseARM64, Anames) -} - -func Rconv(r int) string { - if r == REGG { - return "g" - } - switch { - case REG_R0 <= r && r <= REG_R30: - return fmt.Sprintf("R%d", r-REG_R0) - case r == REG_R31: - return "ZR" - case REG_F0 <= r && r <= REG_F31: - return fmt.Sprintf("F%d", r-REG_F0) - case REG_V0 <= r && r <= REG_V31: - return fmt.Sprintf("V%d", r-REG_V0) - case COND_EQ <= r && r <= COND_NV: - return strcond[r-COND_EQ] - case r == REGSP: - return "RSP" - case r == REG_DAIF: - return "DAIF" - case r == REG_NZCV: - return "NZCV" - case r == REG_FPSR: - return "FPSR" - case r == REG_FPCR: - return "FPCR" - case r == REG_SPSR_EL1: - return "SPSR_EL1" - case r == REG_ELR_EL1: - return "ELR_EL1" - case r == REG_SPSR_EL2: - return "SPSR_EL2" - case r == REG_ELR_EL2: - return "ELR_EL2" - case r == REG_CurrentEL: - return "CurrentEL" - case r == REG_SP_EL0: - return "SP_EL0" - case r == REG_SPSel: - return "SPSel" - case r == REG_DAIFSet: - return "DAIFSet" - case r == REG_DAIFClr: - return "DAIFClr" - } - return fmt.Sprintf("badreg(%d)", r) -} - -func DRconv(a int) string { - if a >= C_NONE && a <= C_NCLASS { - return cnames7[a] - } - return "C_??" -} diff --git a/vendor/github.com/google/gops/internal/obj/arm64/obj7.go b/vendor/github.com/google/gops/internal/obj/arm64/obj7.go deleted file mode 100644 index 2d9d1aa7..00000000 --- a/vendor/github.com/google/gops/internal/obj/arm64/obj7.go +++ /dev/null @@ -1,1005 +0,0 @@ -// cmd/7l/noop.c, cmd/7l/obj.c, cmd/ld/pass.c from Vita Nuova. -// https://code.google.com/p/ken-cc/source/browse/ -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm64 - -import ( - "fmt" - "log" - "math" - - "github.com/google/gops/internal/obj" - "github.com/google/gops/internal/sys" -) - -var complements = []obj.As{ - AADD: ASUB, - AADDW: ASUBW, - ASUB: AADD, - ASUBW: AADDW, - ACMP: ACMN, - ACMPW: ACMNW, - ACMN: ACMP, - ACMNW: ACMPW, -} - -func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { - // MOV g_stackguard(g), R1 - p = obj.Appendp(ctxt, p) - - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - - q := (*obj.Prog)(nil) - if framesize <= obj.StackSmall { - // small stack: SP < stackguard - // MOV SP, R2 - // CMP stackguard, R2 - p = obj.Appendp(ctxt, p) - - p.As = AMOVD - p.From.Type = obj.TYPE_REG - p.From.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.Reg = REG_R2 - } else if framesize <= obj.StackBig { - // large stack: SP-framesize < stackguard-StackSmall - // SUB $framesize, SP, R2 - // CMP stackguard, R2 - p = obj.Appendp(ctxt, p) - - p.As = ASUB - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(framesize) - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.Reg = REG_R2 - } else { - // Such a large stack we need to protect against wraparound - // if SP is close to zero. - // SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // CMP $StackPreempt, R1 - // BEQ label_of_call_to_morestack - // ADD $StackGuard, SP, R2 - // SUB R1, R2 - // MOV $(framesize+(StackGuard-StackSmall)), R3 - // CMP R3, R2 - p = obj.Appendp(ctxt, p) - - p.As = ACMP - p.From.Type = obj.TYPE_CONST - p.From.Offset = obj.StackPreempt - p.Reg = REG_R1 - - p = obj.Appendp(ctxt, p) - q = p - p.As = ABEQ - p.To.Type = obj.TYPE_BRANCH - - p = obj.Appendp(ctxt, p) - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = obj.StackGuard - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = ASUB - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - - p = obj.Appendp(ctxt, p) - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.Reg = REG_R2 - } - - // BLS do-morestack - bls := obj.Appendp(ctxt, p) - bls.As = ABLS - bls.To.Type = obj.TYPE_BRANCH - - var last *obj.Prog - for last = ctxt.Cursym.Text; last.Link != nil; last = last.Link { - } - - // Now we are at the end of the function, but logically - // we are still in function prologue. We need to fix the - // SP data and PCDATA. - spfix := obj.Appendp(ctxt, last) - spfix.As = obj.ANOP - spfix.Spadj = -framesize - - pcdata := obj.Appendp(ctxt, spfix) - pcdata.Lineno = ctxt.Cursym.Text.Lineno - pcdata.Mode = ctxt.Cursym.Text.Mode - pcdata.As = obj.APCDATA - pcdata.From.Type = obj.TYPE_CONST - pcdata.From.Offset = obj.PCDATA_StackMapIndex - pcdata.To.Type = obj.TYPE_CONST - pcdata.To.Offset = -1 // pcdata starts at -1 at function entry - - // MOV LR, R3 - movlr := obj.Appendp(ctxt, pcdata) - movlr.As = AMOVD - movlr.From.Type = obj.TYPE_REG - movlr.From.Reg = REGLINK - movlr.To.Type = obj.TYPE_REG - movlr.To.Reg = REG_R3 - if q != nil { - q.Pcond = movlr - } - bls.Pcond = movlr - - debug := movlr - if false { - debug = obj.Appendp(ctxt, debug) - debug.As = AMOVD - debug.From.Type = obj.TYPE_CONST - debug.From.Offset = int64(framesize) - debug.To.Type = obj.TYPE_REG - debug.To.Reg = REGTMP - } - - // BL runtime.morestack(SB) - call := obj.Appendp(ctxt, debug) - call.As = ABL - call.To.Type = obj.TYPE_BRANCH - morestack := "runtime.morestack" - switch { - case ctxt.Cursym.CFunc(): - morestack = "runtime.morestackc" - case ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0: - morestack = "runtime.morestack_noctxt" - } - call.To.Sym = obj.Linklookup(ctxt, morestack, 0) - - // B start - jmp := obj.Appendp(ctxt, call) - jmp.As = AB - jmp.To.Type = obj.TYPE_BRANCH - jmp.Pcond = ctxt.Cursym.Text.Link - jmp.Spadj = +framesize - - // placeholder for bls's jump target - // p = obj.Appendp(ctxt, p) - // p.As = obj.ANOP - - return bls -} - -func progedit(ctxt *obj.Link, p *obj.Prog) { - p.From.Class = 0 - p.To.Class = 0 - - // $0 results in C_ZCON, which matches both C_REG and various - // C_xCON, however the C_REG cases in asmout don't expect a - // constant, so they will use the register fields and assemble - // a R0. To prevent that, rewrite $0 as ZR. - if p.From.Type == obj.TYPE_CONST && p.From.Offset == 0 { - p.From.Type = obj.TYPE_REG - p.From.Reg = REGZERO - } - if p.To.Type == obj.TYPE_CONST && p.To.Offset == 0 { - p.To.Type = obj.TYPE_REG - p.To.Reg = REGZERO - } - - // Rewrite BR/BL to symbol as TYPE_BRANCH. - switch p.As { - case AB, - ABL, - obj.ARET, - obj.ADUFFZERO, - obj.ADUFFCOPY: - if p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - break - } - - // Rewrite float constants to values stored in memory. - switch p.As { - case AFMOVS: - if p.From.Type == obj.TYPE_FCONST { - f32 := float32(p.From.Val.(float64)) - i32 := math.Float32bits(f32) - if i32 == 0 { - p.From.Type = obj.TYPE_REG - p.From.Reg = REGZERO - break - } - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 4 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - case AFMOVD: - if p.From.Type == obj.TYPE_FCONST { - i64 := math.Float64bits(p.From.Val.(float64)) - if i64 == 0 { - p.From.Type = obj.TYPE_REG - p.From.Reg = REGZERO - break - } - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - break - } - - // Rewrite negative immediates as positive immediates with - // complementary instruction. - switch p.As { - case AADD, ASUB, ACMP, ACMN: - if p.From.Type == obj.TYPE_CONST && p.From.Offset < 0 && p.From.Offset != -1<<63 { - p.From.Offset = -p.From.Offset - p.As = complements[p.As] - } - case AADDW, ASUBW, ACMPW, ACMNW: - if p.From.Type == obj.TYPE_CONST && p.From.Offset < 0 && int32(p.From.Offset) != -1<<31 { - p.From.Offset = -p.From.Offset - p.As = complements[p.As] - } - } - - // For 32-bit logical instruction with constant, - // rewrite the high 32-bit to be a repetition of - // the low 32-bit, so that the BITCON test can be - // shared for both 32-bit and 64-bit. 32-bit ops - // will zero the high 32-bit of the destination - // register anyway. - switch p.As { - case AANDW, AORRW, AEORW, AANDSW: - if p.From.Type == obj.TYPE_CONST { - v := p.From.Offset & 0xffffffff - p.From.Offset = v | v<<32 - } - } - - if ctxt.Flag_dynlink { - rewriteToUseGot(ctxt, p) - } -} - -// Rewrite p, if necessary, to access global data via the global offset table. -func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { - if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { - // ADUFFxxx $offset - // becomes - // MOVD runtime.duffxxx@GOT, REGTMP - // ADD $offset, REGTMP - // CALL REGTMP - var sym *obj.LSym - if p.As == obj.ADUFFZERO { - sym = obj.Linklookup(ctxt, "runtime.duffzero", 0) - } else { - sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0) - } - offset := p.To.Offset - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - p.From.Sym = sym - p.To.Type = obj.TYPE_REG - p.To.Reg = REGTMP - p.To.Name = obj.NAME_NONE - p.To.Offset = 0 - p.To.Sym = nil - p1 := obj.Appendp(ctxt, p) - p1.As = AADD - p1.From.Type = obj.TYPE_CONST - p1.From.Offset = offset - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REGTMP - p2 := obj.Appendp(ctxt, p1) - p2.As = obj.ACALL - p2.To.Type = obj.TYPE_REG - p2.To.Reg = REGTMP - } - - // We only care about global data: NAME_EXTERN means a global - // symbol in the Go sense, and p.Sym.Local is true for a few - // internally defined symbols. - if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - // MOVD $sym, Rx becomes MOVD sym@GOT, Rx - // MOVD $sym+, Rx becomes MOVD sym@GOT, Rx; ADD , Rx - if p.As != AMOVD { - ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p) - } - if p.To.Type != obj.TYPE_REG { - ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p) - } - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - if p.From.Offset != 0 { - q := obj.Appendp(ctxt, p) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = p.From.Offset - q.To = p.To - p.From.Offset = 0 - } - } - if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - var source *obj.Addr - // MOVx sym, Ry becomes MOVD sym@GOT, REGTMP; MOVx (REGTMP), Ry - // MOVx Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP) - // An addition may be inserted between the two MOVs if there is an offset. - if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) - } - source = &p.From - } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - source = &p.To - } else { - return - } - if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { - return - } - if source.Sym.Type == obj.STLSBSS { - return - } - if source.Type != obj.TYPE_MEM { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - p1 := obj.Appendp(ctxt, p) - p2 := obj.Appendp(ctxt, p1) - p1.As = AMOVD - p1.From.Type = obj.TYPE_MEM - p1.From.Sym = source.Sym - p1.From.Name = obj.NAME_GOTREF - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REGTMP - - p2.As = p.As - p2.From = p.From - p2.To = p.To - if p.From.Name == obj.NAME_EXTERN { - p2.From.Reg = REGTMP - p2.From.Name = obj.NAME_NONE - p2.From.Sym = nil - } else if p.To.Name == obj.NAME_EXTERN { - p2.To.Reg = REGTMP - p2.To.Name = obj.NAME_NONE - p2.To.Sym = nil - } else { - return - } - obj.Nopout(p) -} - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func relinv(a obj.As) obj.As { - switch a { - case ABEQ: - return ABNE - case ABNE: - return ABEQ - case ABCS: - return ABCC - case ABHS: - return ABLO - case ABCC: - return ABCS - case ABLO: - return ABHS - case ABMI: - return ABPL - case ABPL: - return ABMI - case ABVS: - return ABVC - case ABVC: - return ABVS - case ABHI: - return ABLS - case ABLS: - return ABHI - case ABGE: - return ABLT - case ABLT: - return ABGE - case ABGT: - return ABLE - case ABLE: - return ABGT - case ACBZ: - return ACBNZ - case ACBNZ: - return ACBZ - case ACBZW: - return ACBNZW - case ACBNZW: - return ACBZW - } - - log.Fatalf("unknown relation: %s", Anames[a-obj.ABaseARM64]) - return 0 -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var r *obj.Prog - var i int - -loop: - if p == nil { - return - } - a := p.As - if a == AB { - q = p.Pcond - if q != nil { - p.Mark |= FOLL - p = q - if !(p.Mark&FOLL != 0) { - goto loop - } - } - } - - if p.Mark&FOLL != 0 { - i = 0 - q = p - for ; i < 4; i, q = i+1, q.Link { - if q == *last || q == nil { - break - } - a = q.As - if a == obj.ANOP { - i-- - continue - } - - if a == AB || a == obj.ARET || a == AERET { - goto copy - } - if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { - continue - } - if a != ABEQ && a != ABNE { - continue - } - - copy: - for { - r = ctxt.NewProg() - *r = *p - if !(r.Mark&FOLL != 0) { - fmt.Printf("can't happen 1\n") - } - r.Mark |= FOLL - if p != q { - p = p.Link - (*last).Link = r - *last = r - continue - } - - (*last).Link = r - *last = r - if a == AB || a == obj.ARET || a == AERET { - return - } - if a == ABNE { - r.As = ABEQ - } else { - r.As = ABNE - } - r.Pcond = p.Link - r.Link = p.Pcond - if !(r.Link.Mark&FOLL != 0) { - xfol(ctxt, r.Link, last) - } - if !(r.Pcond.Mark&FOLL != 0) { - fmt.Printf("can't happen 2\n") - } - return - } - } - - a = AB - q = ctxt.NewProg() - q.As = a - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - p.Mark |= FOLL - (*last).Link = p - *last = p - if a == AB || a == obj.ARET || a == AERET { - return - } - if p.Pcond != nil { - if a != ABL && p.Link != nil { - q = obj.Brchain(ctxt, p.Link) - if a != obj.ATEXT { - if q != nil && (q.Mark&FOLL != 0) { - p.As = relinv(a) - p.Link = p.Pcond - p.Pcond = q - } - } - - xfol(ctxt, p.Link, last) - q = obj.Brchain(ctxt, p.Pcond) - if q == nil { - q = p.Pcond - } - if q.Mark&FOLL != 0 { - p.Pcond = q - return - } - - p = q - goto loop - } - } - - p = p.Link - goto loop -} - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - ctxt.Cursym = cursym - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - p := cursym.Text - textstksiz := p.To.Offset - aoffset := int32(textstksiz) - - cursym.Args = p.To.Val.(int32) - cursym.Locals = int32(textstksiz) - - /* - * find leaf subroutines - * strip NOPs - * expand RET - */ - q := (*obj.Prog)(nil) - var q1 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - switch p.As { - case obj.ATEXT: - p.Mark |= LEAF - - case obj.ARET: - break - - case obj.ANOP: - q1 = p.Link - q.Link = q1 /* q is non-nop */ - q1.Mark |= p.Mark - continue - - case ABL, - obj.ADUFFZERO, - obj.ADUFFCOPY: - cursym.Text.Mark &^= LEAF - fallthrough - - case ACBNZ, - ACBZ, - ACBNZW, - ACBZW, - ATBZ, - ATBNZ, - AB, - ABEQ, - ABNE, - ABCS, - ABHS, - ABCC, - ABLO, - ABMI, - ABPL, - ABVS, - ABVC, - ABHI, - ABLS, - ABGE, - ABLT, - ABGT, - ABLE, - AADR, /* strange */ - AADRP: - q1 = p.Pcond - - if q1 != nil { - for q1.As == obj.ANOP { - q1 = q1.Link - p.Pcond = q1 - } - } - - break - } - - q = p - } - - var q2 *obj.Prog - var retjmp *obj.LSym - for p := cursym.Text; p != nil; p = p.Link { - o := p.As - switch o { - case obj.ATEXT: - cursym.Text = p - if textstksiz < 0 { - ctxt.Autosize = 0 - } else { - ctxt.Autosize = int32(textstksiz + 8) - } - if (cursym.Text.Mark&LEAF != 0) && ctxt.Autosize <= 8 { - ctxt.Autosize = 0 - } else if ctxt.Autosize&(16-1) != 0 { - // The frame includes an LR. - // If the frame size is 8, it's only an LR, - // so there's no potential for breaking references to - // local variables by growing the frame size, - // because there are no local variables. - // But otherwise, if there is a non-empty locals section, - // the author of the code is responsible for making sure - // that the frame size is 8 mod 16. - if ctxt.Autosize == 8 { - ctxt.Autosize += 8 - cursym.Locals += 8 - } else { - ctxt.Diag("%v: unaligned frame size %d - must be 8 mod 16 (or 0)", p, ctxt.Autosize-8) - } - } - p.To.Offset = int64(ctxt.Autosize) - 8 - if ctxt.Autosize == 0 && !(cursym.Text.Mark&LEAF != 0) { - if ctxt.Debugvlog != 0 { - ctxt.Logf("save suppressed in: %s\n", cursym.Text.From.Sym.Name) - } - cursym.Text.Mark |= LEAF - } - - if !(p.From3.Offset&obj.NOSPLIT != 0) { - p = stacksplit(ctxt, p, ctxt.Autosize) // emit split check - } - - aoffset = ctxt.Autosize - if aoffset > 0xF0 { - aoffset = 0xF0 - } - if cursym.Text.Mark&LEAF != 0 { - cursym.Set(obj.AttrLeaf, true) - if ctxt.Autosize == 0 { - break - } - } - - // Frame is non-empty. Make sure to save link register, even if - // it is a leaf function, so that traceback works. - q = p - if ctxt.Autosize > aoffset { - // Frame size is too large for a MOVD.W instruction. - // Store link register before decrementing SP, so if a signal comes - // during the execution of the function prologue, the traceback - // code will not see a half-updated stack frame. - q = obj.Appendp(ctxt, q) - q.Lineno = p.Lineno - q.As = ASUB - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(ctxt.Autosize) - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REGTMP - - q = obj.Appendp(ctxt, q) - q.Lineno = p.Lineno - q.As = AMOVD - q.From.Type = obj.TYPE_REG - q.From.Reg = REGLINK - q.To.Type = obj.TYPE_MEM - q.To.Reg = REGTMP - - q1 = obj.Appendp(ctxt, q) - q1.Lineno = p.Lineno - q1.As = AMOVD - q1.From.Type = obj.TYPE_REG - q1.From.Reg = REGTMP - q1.To.Type = obj.TYPE_REG - q1.To.Reg = REGSP - q1.Spadj = ctxt.Autosize - } else { - // small frame, update SP and save LR in a single MOVD.W instruction - q1 = obj.Appendp(ctxt, q) - q1.As = AMOVD - q1.Lineno = p.Lineno - q1.From.Type = obj.TYPE_REG - q1.From.Reg = REGLINK - q1.To.Type = obj.TYPE_MEM - q1.Scond = C_XPRE - q1.To.Offset = int64(-aoffset) - q1.To.Reg = REGSP - q1.Spadj = aoffset - } - - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOV g_panic(g), R1 - // CMP ZR, R1 - // BEQ end - // MOV panic_argp(R1), R2 - // ADD $(autosize+8), RSP, R3 - // CMP R2, R3 - // BNE end - // ADD $8, RSP, R4 - // MOVD R4, panic_argp(R1) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes. - q = q1 - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_MEM - q.From.Reg = REGG - q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R1 - - q = obj.Appendp(ctxt, q) - q.As = ACMP - q.From.Type = obj.TYPE_REG - q.From.Reg = REGZERO - q.Reg = REG_R1 - - q = obj.Appendp(ctxt, q) - q.As = ABEQ - q.To.Type = obj.TYPE_BRANCH - q1 = q - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_MEM - q.From.Reg = REG_R1 - q.From.Offset = 0 // Panic.argp - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R2 - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(ctxt.Autosize) + 8 - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R3 - - q = obj.Appendp(ctxt, q) - q.As = ACMP - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R2 - q.Reg = REG_R3 - - q = obj.Appendp(ctxt, q) - q.As = ABNE - q.To.Type = obj.TYPE_BRANCH - q2 = q - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = 8 - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R4 - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R4 - q.To.Type = obj.TYPE_MEM - q.To.Reg = REG_R1 - q.To.Offset = 0 // Panic.argp - - q = obj.Appendp(ctxt, q) - - q.As = obj.ANOP - q1.Pcond = q - q2.Pcond = q - } - - case obj.ARET: - nocache(p) - if p.From.Type == obj.TYPE_CONST { - ctxt.Diag("using BECOME (%v) is not supported!", p) - break - } - - retjmp = p.To.Sym - p.To = obj.Addr{} - if cursym.Text.Mark&LEAF != 0 { - if ctxt.Autosize != 0 { - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(ctxt.Autosize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REGSP - p.Spadj = -ctxt.Autosize - } - } else { - /* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/ - aoffset = ctxt.Autosize - - if aoffset > 0xF0 { - aoffset = 0xF0 - } - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.Scond = C_XPOST - p.From.Offset = int64(aoffset) - p.From.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REGLINK - p.Spadj = -aoffset - if ctxt.Autosize > aoffset { - q = ctxt.NewProg() - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(ctxt.Autosize) - int64(aoffset) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Link = p.Link - q.Spadj = int32(-q.From.Offset) - q.Lineno = p.Lineno - p.Link = q - p = q - } - } - - if p.As != obj.ARET { - q = ctxt.NewProg() - q.Lineno = p.Lineno - q.Link = p.Link - p.Link = q - p = q - } - - if retjmp != nil { // retjmp - p.As = AB - p.To.Type = obj.TYPE_BRANCH - p.To.Sym = retjmp - p.Spadj = +ctxt.Autosize - break - } - - p.As = obj.ARET - p.To.Type = obj.TYPE_MEM - p.To.Offset = 0 - p.To.Reg = REGLINK - p.Spadj = +ctxt.Autosize - - case AADD, ASUB: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST { - if p.As == AADD { - p.Spadj = int32(-p.From.Offset) - } else { - p.Spadj = int32(+p.From.Offset) - } - } - break - } - } -} - -func nocache(p *obj.Prog) { - p.Optab = 0 - p.From.Class = 0 - p.To.Class = 0 -} - -var unaryDst = map[obj.As]bool{ - AWORD: true, - ADWORD: true, - ABL: true, - AB: true, - ASVC: true, -} - -var Linkarm64 = obj.LinkArch{ - Arch: sys.ArchARM64, - Preprocess: preprocess, - Assemble: span7, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, -} diff --git a/vendor/github.com/google/gops/internal/obj/data.go b/vendor/github.com/google/gops/internal/obj/data.go deleted file mode 100644 index 0ccb053f..00000000 --- a/vendor/github.com/google/gops/internal/obj/data.go +++ /dev/null @@ -1,190 +0,0 @@ -// Derived from Inferno utils/6l/obj.c and utils/6l/span.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package obj - -import ( - "log" - "math" -) - -// Grow increases the length of s.P to lsiz. -func (s *LSym) Grow(lsiz int64) { - siz := int(lsiz) - if int64(siz) != lsiz { - log.Fatalf("LSym.Grow size %d too long", lsiz) - } - if len(s.P) >= siz { - return - } - // TODO(dfc) append cap-len at once, rather than - // one byte at a time. - for cap(s.P) < siz { - s.P = append(s.P[:cap(s.P)], 0) - } - s.P = s.P[:siz] -} - -// GrowCap increases the capacity of s.P to c. -func (s *LSym) GrowCap(c int64) { - if int64(cap(s.P)) >= c { - return - } - if s.P == nil { - s.P = make([]byte, 0, c) - return - } - b := make([]byte, len(s.P), c) - copy(b, s.P) - s.P = b -} - -// prepwrite prepares to write data of size siz into s at offset off. -func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) { - if off < 0 || siz < 0 || off >= 1<<30 { - log.Fatalf("prepwrite: bad off=%d siz=%d", off, siz) - } - if s.Type == SBSS || s.Type == STLSBSS { - ctxt.Diag("cannot supply data for BSS var") - } - l := off + int64(siz) - s.Grow(l) - if l > s.Size { - s.Size = l - } -} - -// WriteFloat32 writes f into s at offset off. -func (s *LSym) WriteFloat32(ctxt *Link, off int64, f float32) { - s.prepwrite(ctxt, off, 4) - ctxt.Arch.ByteOrder.PutUint32(s.P[off:], math.Float32bits(f)) -} - -// WriteFloat64 writes f into s at offset off. -func (s *LSym) WriteFloat64(ctxt *Link, off int64, f float64) { - s.prepwrite(ctxt, off, 8) - ctxt.Arch.ByteOrder.PutUint64(s.P[off:], math.Float64bits(f)) -} - -// WriteInt writes an integer i of size siz into s at offset off. -func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) { - s.prepwrite(ctxt, off, siz) - switch siz { - default: - ctxt.Diag("WriteInt: bad integer size: %d", siz) - case 1: - s.P[off] = byte(i) - case 2: - ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i)) - case 4: - ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(i)) - case 8: - ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(i)) - } -} - -// WriteAddr writes an address of size siz into s at offset off. -// rsym and roff specify the relocation for the address. -func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) { - if siz != ctxt.Arch.PtrSize { - ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name) - } - s.prepwrite(ctxt, off, siz) - r := Addrel(s) - r.Off = int32(off) - if int64(r.Off) != off { - ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name) - } - r.Siz = uint8(siz) - r.Sym = rsym - r.Type = R_ADDR - r.Add = roff -} - -// WriteOff writes a 4 byte offset to rsym+roff into s at offset off. -// After linking the 4 bytes stored at s+off will be -// rsym+roff-(start of section that s is in). -func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) { - s.prepwrite(ctxt, off, 4) - r := Addrel(s) - r.Off = int32(off) - if int64(r.Off) != off { - ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name) - } - r.Siz = 4 - r.Sym = rsym - r.Type = R_ADDROFF - r.Add = roff -} - -// WriteString writes a string of size siz into s at offset off. -func (s *LSym) WriteString(ctxt *Link, off int64, siz int, str string) { - if siz < len(str) { - ctxt.Diag("WriteString: bad string size: %d < %d", siz, len(str)) - } - s.prepwrite(ctxt, off, siz) - copy(s.P[off:off+int64(siz)], str) -} - -// WriteBytes writes a slice of bytes into s at offset off. -func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 { - s.prepwrite(ctxt, off, len(b)) - copy(s.P[off:], b) - return off + int64(len(b)) -} - -func Addrel(s *LSym) *Reloc { - s.R = append(s.R, Reloc{}) - return &s.R[len(s.R)-1] -} - -func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 { - if s.Type == 0 { - s.Type = SDATA - } - if s.Size < off+wid { - s.Size = off + wid - s.Grow(s.Size) - } - - switch wid { - case 1: - s.P[off] = uint8(v) - case 2: - ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v)) - case 4: - ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v)) - case 8: - ctxt.Arch.ByteOrder.PutUint64(s.P[off:], v) - } - - return off + wid -} diff --git a/vendor/github.com/google/gops/internal/obj/flag.go b/vendor/github.com/google/gops/internal/obj/flag.go deleted file mode 100644 index ff69fd9d..00000000 --- a/vendor/github.com/google/gops/internal/obj/flag.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2015 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 obj - -import ( - "flag" - "fmt" - "os" - "strconv" -) - -func Flagfn2(string, string, func(string, string)) { panic("flag") } - -func Flagcount(name, usage string, val *int) { - flag.Var((*count)(val), name, usage) -} - -func Flagint32(name, usage string, val *int32) { - flag.Var((*int32Value)(val), name, usage) -} - -func Flagint64(name, usage string, val *int64) { - flag.Int64Var(val, name, *val, usage) -} - -func Flagstr(name, usage string, val *string) { - flag.StringVar(val, name, *val, usage) -} - -func Flagfn0(name, usage string, f func()) { - flag.Var(fn0(f), name, usage) -} - -func Flagfn1(name, usage string, f func(string)) { - flag.Var(fn1(f), name, usage) -} - -func Flagprint(fd int) { - if fd == 1 { - flag.CommandLine.SetOutput(os.Stdout) - } - flag.PrintDefaults() -} - -func Flagparse(usage func()) { - flag.Usage = usage - flag.Parse() -} - -// count is a flag.Value that is like a flag.Bool and a flag.Int. -// If used as -name, it increments the count, but -name=x sets the count. -// Used for verbose flag -v. -type count int - -func (c *count) String() string { - return fmt.Sprint(int(*c)) -} - -func (c *count) Set(s string) error { - switch s { - case "true": - *c++ - case "false": - *c = 0 - default: - n, err := strconv.Atoi(s) - if err != nil { - return fmt.Errorf("invalid count %q", s) - } - *c = count(n) - } - return nil -} - -func (c *count) IsBoolFlag() bool { - return true -} - -type int32Value int32 - -func (i *int32Value) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = int32Value(v) - return err -} - -func (i *int32Value) Get() interface{} { return int32(*i) } - -func (i *int32Value) String() string { return fmt.Sprint(*i) } - -type fn0 func() - -func (f fn0) Set(s string) error { - f() - return nil -} - -func (f fn0) Get() interface{} { return nil } - -func (f fn0) String() string { return "" } - -func (f fn0) IsBoolFlag() bool { - return true -} - -type fn1 func(string) - -func (f fn1) Set(s string) error { - f(s) - return nil -} - -func (f fn1) String() string { return "" } diff --git a/vendor/github.com/google/gops/internal/obj/funcdata.go b/vendor/github.com/google/gops/internal/obj/funcdata.go deleted file mode 100644 index 62256a3e..00000000 --- a/vendor/github.com/google/gops/internal/obj/funcdata.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2013 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 obj - -// This file defines the IDs for PCDATA and FUNCDATA instructions -// in Go binaries. It is included by assembly sources, so it must -// be written using #defines. -// -// The Go compiler also #includes this file, for now. -// -// symtab.go also contains a copy of these constants. - -// Pseudo-assembly statements. - -// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros -// that communicate to the runtime information about the location and liveness -// of pointers in an assembly function's arguments, results, and stack frame. -// This communication is only required in assembly functions that make calls -// to other functions that might be preempted or grow the stack. -// NOSPLIT functions that make no calls do not need to use these macros. - -// GO_ARGS indicates that the Go prototype for this assembly function -// defines the pointer map for the function's arguments. -// GO_ARGS should be the first instruction in a function that uses it. -// It can be omitted if there are no arguments at all. -// GO_ARGS is inserted implicitly by the linker for any function -// that also has a Go prototype and therefore is usually not necessary -// to write explicitly. - -// GO_RESULTS_INITIALIZED indicates that the assembly function -// has initialized the stack space for its results and that those results -// should be considered live for the remainder of the function. - -// NO_LOCAL_POINTERS indicates that the assembly function stores -// no pointers to heap objects in its local stack variables. - -// ArgsSizeUnknown is set in Func.argsize to mark all functions -// whose argument size is unknown (C vararg functions, and -// assembly code without an explicit specification). -// This value is generated by the compiler, assembler, or linker. -const ( - PCDATA_StackMapIndex = 0 - FUNCDATA_ArgsPointerMaps = 0 - FUNCDATA_LocalsPointerMaps = 1 - ArgsSizeUnknown = -0x80000000 -) diff --git a/vendor/github.com/google/gops/internal/obj/go.go b/vendor/github.com/google/gops/internal/obj/go.go deleted file mode 100644 index 1852dc74..00000000 --- a/vendor/github.com/google/gops/internal/obj/go.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2009 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 obj - -import ( - "fmt" - "os" - "strings" -) - -// go-specific code shared across loaders (5l, 6l, 8l). - -var ( - framepointer_enabled int - Fieldtrack_enabled int -) - -// Toolchain experiments. -// These are controlled by the GOEXPERIMENT environment -// variable recorded when the toolchain is built. -// This list is also known to cmd/gc. -var exper = []struct { - name string - val *int -}{ - {"fieldtrack", &Fieldtrack_enabled}, - {"framepointer", &framepointer_enabled}, -} - -func addexp(s string) { - // Could do general integer parsing here, but the runtime copy doesn't yet. - v := 1 - name := s - if len(name) > 2 && name[:2] == "no" { - v = 0 - name = name[2:] - } - for i := 0; i < len(exper); i++ { - if exper[i].name == name { - if exper[i].val != nil { - *exper[i].val = v - } - return - } - } - - fmt.Printf("unknown experiment %s\n", s) - os.Exit(2) -} - -func init() { - framepointer_enabled = 1 // default - for _, f := range strings.Split(goexperiment, ",") { - if f != "" { - addexp(f) - } - } -} - -func Framepointer_enabled(goos, goarch string) bool { - return framepointer_enabled != 0 && goarch == "amd64" && goos != "nacl" -} - -func Nopout(p *Prog) { - p.As = ANOP - p.Scond = 0 - p.From = Addr{} - p.From3 = nil - p.Reg = 0 - p.To = Addr{} -} - -func Expstring() string { - buf := "X" - for i := range exper { - if *exper[i].val != 0 { - buf += "," + exper[i].name - } - } - if buf == "X" { - buf += ",none" - } - return "X:" + buf[2:] -} diff --git a/vendor/github.com/google/gops/internal/obj/ld.go b/vendor/github.com/google/gops/internal/obj/ld.go deleted file mode 100644 index 54fde2f2..00000000 --- a/vendor/github.com/google/gops/internal/obj/ld.go +++ /dev/null @@ -1,92 +0,0 @@ -// Derived from Inferno utils/6l/obj.c and utils/6l/span.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package obj - -/* - * add library to library list. - * srcref: src file referring to package - * objref: object file referring to package - * file: object file, e.g., /home/rsc/go/pkg/container/vector.a - * pkg: package import path, e.g. container/vector - */ - -const ( - LOG = 5 -) - -func mkfwd(sym *LSym) { - var dwn [LOG]int32 - var cnt [LOG]int32 - var lst [LOG]*Prog - - for i := 0; i < LOG; i++ { - if i == 0 { - cnt[i] = 1 - } else { - cnt[i] = LOG * cnt[i-1] - } - dwn[i] = 1 - lst[i] = nil - } - - i := 0 - for p := sym.Text; p != nil && p.Link != nil; p = p.Link { - i-- - if i < 0 { - i = LOG - 1 - } - p.Forwd = nil - dwn[i]-- - if dwn[i] <= 0 { - dwn[i] = cnt[i] - if lst[i] != nil { - lst[i].Forwd = p - } - lst[i] = p - } - } -} - -func Copyp(ctxt *Link, q *Prog) *Prog { - p := ctxt.NewProg() - *p = *q - return p -} - -func Appendp(ctxt *Link, q *Prog) *Prog { - p := ctxt.NewProg() - p.Link = q.Link - q.Link = p - p.Lineno = q.Lineno - p.Mode = q.Mode - return p -} diff --git a/vendor/github.com/google/gops/internal/obj/link.go b/vendor/github.com/google/gops/internal/obj/link.go deleted file mode 100644 index e2530615..00000000 --- a/vendor/github.com/google/gops/internal/obj/link.go +++ /dev/null @@ -1,974 +0,0 @@ -// Derived from Inferno utils/6l/l.h and related files. -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package obj - -import ( - "bufio" - "fmt" - - "github.com/google/gops/internal/sys" -) - -// An Addr is an argument to an instruction. -// The general forms and their encodings are: -// -// sym±offset(symkind)(reg)(index*scale) -// Memory reference at address &sym(symkind) + offset + reg + index*scale. -// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted. -// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg). -// To force a parsing as index*scale, write (index*1). -// Encoding: -// type = TYPE_MEM -// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE) -// sym = sym -// offset = ±offset -// reg = reg (REG_*) -// index = index (REG_*) -// scale = scale (1, 2, 4, 8) -// -// $ -// Effective address of memory reference , defined above. -// Encoding: same as memory reference, but type = TYPE_ADDR. -// -// $<±integer value> -// This is a special case of $, in which only ±offset is present. -// It has a separate type for easy recognition. -// Encoding: -// type = TYPE_CONST -// offset = ±integer value -// -// * -// Indirect reference through memory reference , defined above. -// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function -// pointer stored in the data word sym(SB), not a function named sym(SB). -// Encoding: same as above, but type = TYPE_INDIR. -// -// $*$ -// No longer used. -// On machines with actual SB registers, $*$ forced the -// instruction encoding to use a full 32-bit constant, never a -// reference relative to SB. -// -// $ -// Floating point constant value. -// Encoding: -// type = TYPE_FCONST -// val = floating point value -// -// $ -// String literal value (raw bytes used for DATA instruction). -// Encoding: -// type = TYPE_SCONST -// val = string -// -// -// Any register: integer, floating point, control, segment, and so on. -// If looking for specific register kind, must check type and reg value range. -// Encoding: -// type = TYPE_REG -// reg = reg (REG_*) -// -// x(PC) -// Encoding: -// type = TYPE_BRANCH -// val = Prog* reference OR ELSE offset = target pc (branch takes priority) -// -// $±x-±y -// Final argument to TEXT, specifying local frame size x and argument size y. -// In this form, x and y are integer literals only, not arbitrary expressions. -// This avoids parsing ambiguities due to the use of - as a separator. -// The ± are optional. -// If the final argument to TEXT omits the -±y, the encoding should still -// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown. -// Encoding: -// type = TYPE_TEXTSIZE -// offset = x -// val = int32(y) -// -// reg<>shift, reg->shift, reg@>shift -// Shifted register value, for ARM and ARM64. -// In this form, reg must be a register and shift can be a register or an integer constant. -// Encoding: -// type = TYPE_SHIFT -// On ARM: -// offset = (reg&15) | shifttype<<5 | count -// shifttype = 0, 1, 2, 3 for <<, >>, ->, @> -// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant. -// On ARM64: -// offset = (reg&31)<<16 | shifttype<<22 | (count&63)<<10 -// shifttype = 0, 1, 2 for <<, >>, -> -// -// (reg, reg) -// A destination register pair. When used as the last argument of an instruction, -// this form makes clear that both registers are destinations. -// Encoding: -// type = TYPE_REGREG -// reg = first register -// offset = second register -// -// [reg, reg, reg-reg] -// Register list for ARM. -// Encoding: -// type = TYPE_REGLIST -// offset = bit mask of registers in list; R0 is low bit. -// -// reg, reg -// Register pair for ARM. -// TYPE_REGREG2 -// -// (reg+reg) -// Register pair for PPC64. -// Encoding: -// type = TYPE_MEM -// reg = first register -// index = second register -// scale = 1 -// -type Addr struct { - Reg int16 - Index int16 - Scale int16 // Sometimes holds a register. - Type AddrType - Name int8 - Class int8 - Offset int64 - Sym *LSym - - // argument value: - // for TYPE_SCONST, a string - // for TYPE_FCONST, a float64 - // for TYPE_BRANCH, a *Prog (optional) - // for TYPE_TEXTSIZE, an int32 (optional) - Val interface{} - - Node interface{} // for use by compiler -} - -type AddrType uint8 - -const ( - NAME_NONE = 0 + iota - NAME_EXTERN - NAME_STATIC - NAME_AUTO - NAME_PARAM - // A reference to name@GOT(SB) is a reference to the entry in the global offset - // table for 'name'. - NAME_GOTREF -) - -const ( - TYPE_NONE AddrType = 0 - - TYPE_BRANCH AddrType = 5 + iota - TYPE_TEXTSIZE - TYPE_MEM - TYPE_CONST - TYPE_FCONST - TYPE_SCONST - TYPE_REG - TYPE_ADDR - TYPE_SHIFT - TYPE_REGREG - TYPE_REGREG2 - TYPE_INDIR - TYPE_REGLIST -) - -// Prog describes a single machine instruction. -// -// The general instruction form is: -// -// As.Scond From, Reg, From3, To, RegTo2 -// -// where As is an opcode and the others are arguments: -// From, Reg, From3 are sources, and To, RegTo2 are destinations. -// Usually, not all arguments are present. -// For example, MOVL R1, R2 encodes using only As=MOVL, From=R1, To=R2. -// The Scond field holds additional condition bits for systems (like arm) -// that have generalized conditional execution. -// -// Jump instructions use the Pcond field to point to the target instruction, -// which must be in the same linked list as the jump instruction. -// -// The Progs for a given function are arranged in a list linked through the Link field. -// -// Each Prog is charged to a specific source line in the debug information, -// specified by Lineno, an index into the line history (see LineHist). -// Every Prog has a Ctxt field that defines various context, including the current LineHist. -// Progs should be allocated using ctxt.NewProg(), not new(Prog). -// -// The other fields not yet mentioned are for use by the back ends and should -// be left zeroed by creators of Prog lists. -type Prog struct { - Ctxt *Link // linker context - Link *Prog // next Prog in linked list - From Addr // first source operand - From3 *Addr // third source operand (second is Reg below) - To Addr // destination operand (second is RegTo2 below) - Pcond *Prog // target of conditional jump - Opt interface{} // available to optimization passes to hold per-Prog state - Forwd *Prog // for x86 back end - Rel *Prog // for x86, arm back ends - Pc int64 // for back ends or assembler: virtual or actual program counter, depending on phase - Lineno int32 // line number of this instruction - Spadj int32 // effect of instruction on stack pointer (increment or decrement amount) - As As // assembler opcode - Reg int16 // 2nd source operand - RegTo2 int16 // 2nd destination operand - Mark uint16 // bitmask of arch-specific items - Optab uint16 // arch-specific opcode index - Scond uint8 // condition bits for conditional instruction (e.g., on ARM) - Back uint8 // for x86 back end: backwards branch state - Ft uint8 // for x86 back end: type index of Prog.From - Tt uint8 // for x86 back end: type index of Prog.To - Isize uint8 // for x86 back end: size of the instruction in bytes - Mode int8 // for x86 back end: 32- or 64-bit mode -} - -// From3Type returns From3.Type, or TYPE_NONE when From3 is nil. -func (p *Prog) From3Type() AddrType { - if p.From3 == nil { - return TYPE_NONE - } - return p.From3.Type -} - -// From3Offset returns From3.Offset, or 0 when From3 is nil. -func (p *Prog) From3Offset() int64 { - if p.From3 == nil { - return 0 - } - return p.From3.Offset -} - -// An As denotes an assembler opcode. -// There are some portable opcodes, declared here in package obj, -// that are common to all architectures. -// However, the majority of opcodes are arch-specific -// and are declared in their respective architecture's subpackage. -type As int16 - -// These are the portable opcodes. -const ( - AXXX As = iota - ACALL - ADUFFCOPY - ADUFFZERO - AEND - AFUNCDATA - AJMP - ANOP - APCDATA - ARET - ATEXT - ATYPE - AUNDEF - AUSEFIELD - AVARDEF - AVARKILL - AVARLIVE - A_ARCHSPECIFIC -) - -// Each architecture is allotted a distinct subspace of opcode values -// for declaring its arch-specific opcodes. -// Within this subspace, the first arch-specific opcode should be -// at offset A_ARCHSPECIFIC. -// -// Subspaces are aligned to a power of two so opcodes can be masked -// with AMask and used as compact array indices. -const ( - ABase386 = (1 + iota) << 10 - ABaseARM - ABaseAMD64 - ABasePPC64 - ABaseARM64 - ABaseMIPS64 - ABaseS390X - - AllowedOpCodes = 1 << 10 // The number of opcodes available for any given architecture. - AMask = AllowedOpCodes - 1 // AND with this to use the opcode as an array index. -) - -// An LSym is the sort of symbol that is written to an object file. -type LSym struct { - Name string - Type SymKind - Version int16 - Attribute - - RefIdx int // Index of this symbol in the symbol reference list. - Args int32 - Locals int32 - Size int64 - Gotype *LSym - Autom *Auto - Text *Prog - Pcln *Pcln - P []byte - R []Reloc -} - -// Attribute is a set of symbol attributes. -type Attribute int16 - -const ( - AttrDuplicateOK Attribute = 1 << iota - AttrCFunc - AttrNoSplit - AttrLeaf - AttrSeenGlobl - AttrOnList - - // MakeTypelink means that the type should have an entry in the typelink table. - AttrMakeTypelink - - // ReflectMethod means the function may call reflect.Type.Method or - // reflect.Type.MethodByName. Matching is imprecise (as reflect.Type - // can be used through a custom interface), so ReflectMethod may be - // set in some cases when the reflect package is not called. - // - // Used by the linker to determine what methods can be pruned. - AttrReflectMethod - - // Local means make the symbol local even when compiling Go code to reference Go - // symbols in other shared libraries, as in this mode symbols are global by - // default. "local" here means in the sense of the dynamic linker, i.e. not - // visible outside of the module (shared library or executable) that contains its - // definition. (When not compiling to support Go shared libraries, all symbols are - // local in this sense unless there is a cgo_export_* directive). - AttrLocal -) - -func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } -func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 } -func (a Attribute) CFunc() bool { return a&AttrCFunc != 0 } -func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } -func (a Attribute) Leaf() bool { return a&AttrLeaf != 0 } -func (a Attribute) SeenGlobl() bool { return a&AttrSeenGlobl != 0 } -func (a Attribute) OnList() bool { return a&AttrOnList != 0 } -func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } -func (a Attribute) Local() bool { return a&AttrLocal != 0 } - -func (a *Attribute) Set(flag Attribute, value bool) { - if value { - *a |= flag - } else { - *a &^= flag - } -} - -// The compiler needs LSym to satisfy fmt.Stringer, because it stores -// an LSym in ssa.ExternSymbol. -func (s *LSym) String() string { - return s.Name -} - -type Pcln struct { - Pcsp Pcdata - Pcfile Pcdata - Pcline Pcdata - Pcdata []Pcdata - Funcdata []*LSym - Funcdataoff []int64 - File []*LSym - Lastfile *LSym - Lastindex int -} - -// A SymKind describes the kind of memory represented by a symbol. -type SymKind int16 - -// Defined SymKind values. -// -// TODO(rsc): Give idiomatic Go names. -// TODO(rsc): Reduce the number of symbol types in the object files. -//go:generate stringer -type=SymKind -const ( - Sxxx SymKind = iota - STEXT - SELFRXSECT - - // Read-only sections. - STYPE - SSTRING - SGOSTRING - SGOFUNC - SGCBITS - SRODATA - SFUNCTAB - - SELFROSECT - SMACHOPLT - - // Read-only sections with relocations. - // - // Types STYPE-SFUNCTAB above are written to the .rodata section by default. - // When linking a shared object, some conceptually "read only" types need to - // be written to by relocations and putting them in a section called - // ".rodata" interacts poorly with the system linkers. The GNU linkers - // support this situation by arranging for sections of the name - // ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after - // relocations have applied, so when the Go linker is creating a shared - // object it checks all objects of the above types and bumps any object that - // has a relocation to it to the corresponding type below, which are then - // written to sections with appropriate magic names. - STYPERELRO - SSTRINGRELRO - SGOSTRINGRELRO - SGOFUNCRELRO - SGCBITSRELRO - SRODATARELRO - SFUNCTABRELRO - - // Part of .data.rel.ro if it exists, otherwise part of .rodata. - STYPELINK - SITABLINK - SSYMTAB - SPCLNTAB - - // Writable sections. - SELFSECT - SMACHO - SMACHOGOT - SWINDOWS - SELFGOT - SNOPTRDATA - SINITARR - SDATA - SBSS - SNOPTRBSS - STLSBSS - SXREF - SMACHOSYMSTR - SMACHOSYMTAB - SMACHOINDIRECTPLT - SMACHOINDIRECTGOT - SFILE - SFILEPATH - SCONST - SDYNIMPORT - SHOSTOBJ - SDWARFSECT - SDWARFINFO - SSUB = SymKind(1 << 8) - SMASK = SymKind(SSUB - 1) - SHIDDEN = SymKind(1 << 9) - SCONTAINER = SymKind(1 << 10) // has a sub-symbol -) - -// ReadOnly are the symbol kinds that form read-only sections. In some -// cases, if they will require relocations, they are transformed into -// rel-ro sections using RelROMap. -var ReadOnly = []SymKind{ - STYPE, - SSTRING, - SGOSTRING, - SGOFUNC, - SGCBITS, - SRODATA, - SFUNCTAB, -} - -// RelROMap describes the transformation of read-only symbols to rel-ro -// symbols. -var RelROMap = map[SymKind]SymKind{ - STYPE: STYPERELRO, - SSTRING: SSTRINGRELRO, - SGOSTRING: SGOSTRINGRELRO, - SGOFUNC: SGOFUNCRELRO, - SGCBITS: SGCBITSRELRO, - SRODATA: SRODATARELRO, - SFUNCTAB: SFUNCTABRELRO, -} - -type Reloc struct { - Off int32 - Siz uint8 - Type RelocType - Add int64 - Sym *LSym -} - -type RelocType int32 - -//go:generate stringer -type=RelocType -const ( - R_ADDR RelocType = 1 + iota - // R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit - // immediates in the low half of the instruction word), usually addis followed by - // another add or a load, inserting the "high adjusted" 16 bits of the address of - // the referenced symbol into the immediate field of the first instruction and the - // low 16 bits into that of the second instruction. - R_ADDRPOWER - // R_ADDRARM64 relocates an adrp, add pair to compute the address of the - // referenced symbol. - R_ADDRARM64 - // R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external - // address, by encoding it into the instruction. - R_ADDRMIPS - // R_ADDROFF resolves to a 32-bit offset from the beginning of the section - // holding the data being relocated to the referenced symbol. - R_ADDROFF - R_SIZE - R_CALL - R_CALLARM - R_CALLARM64 - R_CALLIND - R_CALLPOWER - // R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address - // of a CALL (JAL) instruction, by encoding the address into the instruction. - R_CALLMIPS - R_CONST - R_PCREL - // R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the - // thread-local symbol from the thread local base and is used to implement the - // "local exec" model for tls access (r.Sym is not set on intel platforms but is - // set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking). - R_TLS_LE - // R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT - // slot containing the offset from the thread-local symbol from the thread local - // base and is used to implemented the "initial exec" model for tls access (r.Sym - // is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in - // the linker when externally linking). - R_TLS_IE - R_GOTOFF - R_PLT0 - R_PLT1 - R_PLT2 - R_USEFIELD - // R_USETYPE resolves to an *rtype, but no relocation is created. The - // linker uses this as a signal that the pointed-to type information - // should be linked into the final binary, even if there are no other - // direct references. (This is used for types reachable by reflection.) - R_USETYPE - // R_METHODOFF resolves to a 32-bit offset from the beginning of the section - // holding the data being relocated to the referenced symbol. - // It is a variant of R_ADDROFF used when linking from the uncommonType of a - // *rtype, and may be set to zero by the linker if it determines the method - // text is unreachable by the linked program. - R_METHODOFF - R_POWER_TOC - R_GOTPCREL - // R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address - // of a JMP instruction, by encoding the address into the instruction. - // The stack nosplit check ignores this since it is not a function call. - R_JMPMIPS - // R_DWARFREF resolves to the offset of the symbol from its section. - R_DWARFREF - - // Platform dependent relocations. Architectures with fixed width instructions - // have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be - // stuffed into a 32-bit instruction, so an address needs to be spread across - // several instructions, and in turn this requires a sequence of relocations, each - // updating a part of an instruction. This leads to relocation codes that are - // inherently processor specific. - - // Arm64. - - // Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread - // local base to the thread local variable defined by the referenced (thread - // local) symbol. Error if the offset does not fit into 16 bits. - R_ARM64_TLS_LE - - // Relocates an ADRP; LD64 instruction sequence to load the offset between - // the thread local base and the thread local variable defined by the - // referenced (thread local) symbol from the GOT. - R_ARM64_TLS_IE - - // R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT - // slot of the referenced symbol. - R_ARM64_GOTPCREL - - // PPC64. - - // R_POWER_TLS_LE is used to implement the "local exec" model for tls - // access. It resolves to the offset of the thread-local symbol from the - // thread pointer (R13) and inserts this value into the low 16 bits of an - // instruction word. - R_POWER_TLS_LE - - // R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It - // relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It - // inserts to the offset of GOT slot for the thread-local symbol from the TOC (the - // GOT slot is filled by the dynamic linker with the offset of the thread-local - // symbol from the thread pointer (R13)). - R_POWER_TLS_IE - - // R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as - // accessing a particular thread-local symbol. It does not affect code generation - // but is used by the system linker when relaxing "initial exec" model code to - // "local exec" model code. - R_POWER_TLS - - // R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second - // instruction is a "DS-form" instruction, which has an immediate field occupying - // bits [15:2] of the instruction word. Bits [15:2] of the address of the - // relocated symbol are inserted into this field; it is an error if the last two - // bits of the address are not 0. - R_ADDRPOWER_DS - - // R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like - // R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol - // from the TOC rather than the symbol's address. - R_ADDRPOWER_GOT - - // R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but - // inserts the displacement from the place being relocated to the address of the - // the relocated symbol instead of just its address. - R_ADDRPOWER_PCREL - - // R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but - // inserts the offset from the TOC to the address of the the relocated symbol - // rather than the symbol's address. - R_ADDRPOWER_TOCREL - - // R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like - // R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the - // relocated symbol rather than the symbol's address. - R_ADDRPOWER_TOCREL_DS - - // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. - // TODO(mundaym): remove once variants can be serialized - see issue 14218. - R_PCRELDBL - - // R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16 - // bits (bit 16-31) of an external address, by encoding it into the instruction. - R_ADDRMIPSU - // R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS - // address (offset from thread pointer), by encoding it into the instruction. - R_ADDRMIPSTLS -) - -// IsDirectJump returns whether r is a relocation for a direct jump. -// A direct jump is a CALL or JMP instruction that takes the target address -// as immediate. The address is embedded into the instruction, possibly -// with limited width. -// An indirect jump is a CALL or JMP instruction that takes the target address -// in register or memory. -func (r RelocType) IsDirectJump() bool { - switch r { - case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS: - return true - } - return false -} - -type Auto struct { - Asym *LSym - Link *Auto - Aoffset int32 - Name int16 - Gotype *LSym -} - -// Auto.name -const ( - A_AUTO = 1 + iota - A_PARAM -) - -type Pcdata struct { - P []byte -} - -// symbol version, incremented each time a file is loaded. -// version==1 is reserved for savehist. -const ( - HistVersion = 1 -) - -// Link holds the context for writing object code from a compiler -// to be linker input or for reading that input into the linker. -type Link struct { - Headtype HeadType - Arch *LinkArch - Debugasm int32 - Debugvlog int32 - Debugdivmod int32 - Debugpcln int32 - Flag_shared bool - Flag_dynlink bool - Flag_optimize bool - Bso *bufio.Writer - Pathname string - Hash map[SymVer]*LSym - LineHist LineHist - Imports []string - Plists []*Plist - Sym_div *LSym - Sym_divu *LSym - Sym_mod *LSym - Sym_modu *LSym - Plan9privates *LSym - Curp *Prog - Printp *Prog - Blitrl *Prog - Elitrl *Prog - Rexflag int - Vexflag int - Rep int - Repn int - Lock int - Asmode int - AsmBuf AsmBuf // instruction buffer for x86 - Instoffset int64 - Autosize int32 - Armsize int32 - Pc int64 - DiagFunc func(string, ...interface{}) - Mode int - Cursym *LSym - Version int - Errors int - - Framepointer_enabled bool - - // state for writing objects - Text []*LSym - Data []*LSym - - // Cache of Progs - allocIdx int - progs [10000]Prog -} - -func (ctxt *Link) Diag(format string, args ...interface{}) { - ctxt.Errors++ - ctxt.DiagFunc(format, args...) -} - -func (ctxt *Link) Logf(format string, args ...interface{}) { - fmt.Fprintf(ctxt.Bso, format, args...) - ctxt.Bso.Flush() -} - -// The smallest possible offset from the hardware stack pointer to a local -// variable on the stack. Architectures that use a link register save its value -// on the stack in the function prologue and so always have a pointer between -// the hardware stack pointer and the local variable area. -func (ctxt *Link) FixedFrameSize() int64 { - switch ctxt.Arch.Family { - case sys.AMD64, sys.I386: - return 0 - case sys.PPC64: - // PIC code on ppc64le requires 32 bytes of stack, and it's easier to - // just use that much stack always on ppc64x. - return int64(4 * ctxt.Arch.PtrSize) - default: - return int64(ctxt.Arch.PtrSize) - } -} - -type SymVer struct { - Name string - Version int // TODO: make int16 to match LSym.Version? -} - -// LinkArch is the definition of a single architecture. -type LinkArch struct { - *sys.Arch - Preprocess func(*Link, *LSym) - Assemble func(*Link, *LSym) - Follow func(*Link, *LSym) - Progedit func(*Link, *Prog) - UnaryDst map[As]bool // Instruction takes one operand, a destination. -} - -// HeadType is the executable header type. -type HeadType uint8 - -const ( - Hunknown HeadType = iota - Hdarwin - Hdragonfly - Hfreebsd - Hlinux - Hnacl - Hnetbsd - Hopenbsd - Hplan9 - Hsolaris - Hwindows - Hwindowsgui -) - -func (h *HeadType) Set(s string) error { - switch s { - case "darwin": - *h = Hdarwin - case "dragonfly": - *h = Hdragonfly - case "freebsd": - *h = Hfreebsd - case "linux", "android": - *h = Hlinux - case "nacl": - *h = Hnacl - case "netbsd": - *h = Hnetbsd - case "openbsd": - *h = Hopenbsd - case "plan9": - *h = Hplan9 - case "solaris": - *h = Hsolaris - case "windows": - *h = Hwindows - case "windowsgui": - *h = Hwindowsgui - default: - return fmt.Errorf("invalid headtype: %q", s) - } - return nil -} - -func (h *HeadType) String() string { - switch *h { - case Hdarwin: - return "darwin" - case Hdragonfly: - return "dragonfly" - case Hfreebsd: - return "freebsd" - case Hlinux: - return "linux" - case Hnacl: - return "nacl" - case Hnetbsd: - return "netbsd" - case Hopenbsd: - return "openbsd" - case Hplan9: - return "plan9" - case Hsolaris: - return "solaris" - case Hwindows: - return "windows" - case Hwindowsgui: - return "windowsgui" - } - return fmt.Sprintf("HeadType(%d)", *h) -} - -// AsmBuf is a simple buffer to assemble variable-length x86 instructions into. -type AsmBuf struct { - buf [100]byte - off int -} - -// Put1 appends one byte to the end of the buffer. -func (a *AsmBuf) Put1(x byte) { - a.buf[a.off] = x - a.off++ -} - -// Put2 appends two bytes to the end of the buffer. -func (a *AsmBuf) Put2(x, y byte) { - a.buf[a.off+0] = x - a.buf[a.off+1] = y - a.off += 2 -} - -// Put3 appends three bytes to the end of the buffer. -func (a *AsmBuf) Put3(x, y, z byte) { - a.buf[a.off+0] = x - a.buf[a.off+1] = y - a.buf[a.off+2] = z - a.off += 3 -} - -// Put4 appends four bytes to the end of the buffer. -func (a *AsmBuf) Put4(x, y, z, w byte) { - a.buf[a.off+0] = x - a.buf[a.off+1] = y - a.buf[a.off+2] = z - a.buf[a.off+3] = w - a.off += 4 -} - -// PutInt16 writes v into the buffer using little-endian encoding. -func (a *AsmBuf) PutInt16(v int16) { - a.buf[a.off+0] = byte(v) - a.buf[a.off+1] = byte(v >> 8) - a.off += 2 -} - -// PutInt32 writes v into the buffer using little-endian encoding. -func (a *AsmBuf) PutInt32(v int32) { - a.buf[a.off+0] = byte(v) - a.buf[a.off+1] = byte(v >> 8) - a.buf[a.off+2] = byte(v >> 16) - a.buf[a.off+3] = byte(v >> 24) - a.off += 4 -} - -// PutInt64 writes v into the buffer using little-endian encoding. -func (a *AsmBuf) PutInt64(v int64) { - a.buf[a.off+0] = byte(v) - a.buf[a.off+1] = byte(v >> 8) - a.buf[a.off+2] = byte(v >> 16) - a.buf[a.off+3] = byte(v >> 24) - a.buf[a.off+4] = byte(v >> 32) - a.buf[a.off+5] = byte(v >> 40) - a.buf[a.off+6] = byte(v >> 48) - a.buf[a.off+7] = byte(v >> 56) - a.off += 8 -} - -// Put copies b into the buffer. -func (a *AsmBuf) Put(b []byte) { - copy(a.buf[a.off:], b) - a.off += len(b) -} - -// Insert inserts b at offset i. -func (a *AsmBuf) Insert(i int, b byte) { - a.off++ - copy(a.buf[i+1:a.off], a.buf[i:a.off-1]) - a.buf[i] = b -} - -// Last returns the byte at the end of the buffer. -func (a *AsmBuf) Last() byte { return a.buf[a.off-1] } - -// Len returns the length of the buffer. -func (a *AsmBuf) Len() int { return a.off } - -// Bytes returns the contents of the buffer. -func (a *AsmBuf) Bytes() []byte { return a.buf[:a.off] } - -// Reset empties the buffer. -func (a *AsmBuf) Reset() { a.off = 0 } - -// Peek returns the byte at offset i. -func (a *AsmBuf) Peek(i int) byte { return a.buf[i] } diff --git a/vendor/github.com/google/gops/internal/obj/mips/a.out.go b/vendor/github.com/google/gops/internal/obj/mips/a.out.go deleted file mode 100644 index e0e51eed..00000000 --- a/vendor/github.com/google/gops/internal/obj/mips/a.out.go +++ /dev/null @@ -1,375 +0,0 @@ -// cmd/9c/9.out.h from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package mips - -import "github.com/google/gops/internal/obj" - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p mips - -/* - * mips 64 - */ -const ( - NSNAME = 8 - NSYM = 50 - NREG = 32 /* number of general registers */ - NFREG = 32 /* number of floating point registers */ -) - -const ( - REG_R0 = obj.RBaseMIPS64 + iota - REG_R1 - REG_R2 - REG_R3 - REG_R4 - REG_R5 - REG_R6 - REG_R7 - REG_R8 - REG_R9 - REG_R10 - REG_R11 - REG_R12 - REG_R13 - REG_R14 - REG_R15 - REG_R16 - REG_R17 - REG_R18 - REG_R19 - REG_R20 - REG_R21 - REG_R22 - REG_R23 - REG_R24 - REG_R25 - REG_R26 - REG_R27 - REG_R28 - REG_R29 - REG_R30 - REG_R31 - - REG_F0 - REG_F1 - REG_F2 - REG_F3 - REG_F4 - REG_F5 - REG_F6 - REG_F7 - REG_F8 - REG_F9 - REG_F10 - REG_F11 - REG_F12 - REG_F13 - REG_F14 - REG_F15 - REG_F16 - REG_F17 - REG_F18 - REG_F19 - REG_F20 - REG_F21 - REG_F22 - REG_F23 - REG_F24 - REG_F25 - REG_F26 - REG_F27 - REG_F28 - REG_F29 - REG_F30 - REG_F31 - - REG_HI - REG_LO - - // co-processor 0 control registers - REG_M0 - REG_M1 - REG_M2 - REG_M3 - REG_M4 - REG_M5 - REG_M6 - REG_M7 - REG_M8 - REG_M9 - REG_M10 - REG_M11 - REG_M12 - REG_M13 - REG_M14 - REG_M15 - REG_M16 - REG_M17 - REG_M18 - REG_M19 - REG_M20 - REG_M21 - REG_M22 - REG_M23 - REG_M24 - REG_M25 - REG_M26 - REG_M27 - REG_M28 - REG_M29 - REG_M30 - REG_M31 - - // FPU control registers - REG_FCR0 - REG_FCR1 - REG_FCR2 - REG_FCR3 - REG_FCR4 - REG_FCR5 - REG_FCR6 - REG_FCR7 - REG_FCR8 - REG_FCR9 - REG_FCR10 - REG_FCR11 - REG_FCR12 - REG_FCR13 - REG_FCR14 - REG_FCR15 - REG_FCR16 - REG_FCR17 - REG_FCR18 - REG_FCR19 - REG_FCR20 - REG_FCR21 - REG_FCR22 - REG_FCR23 - REG_FCR24 - REG_FCR25 - REG_FCR26 - REG_FCR27 - REG_FCR28 - REG_FCR29 - REG_FCR30 - REG_FCR31 - - REG_LAST = REG_FCR31 // the last defined register - - REG_SPECIAL = REG_M0 - - REGZERO = REG_R0 /* set to zero */ - REGSP = REG_R29 - REGSB = REG_R28 - REGLINK = REG_R31 - REGRET = REG_R1 - REGARG = -1 /* -1 disables passing the first argument in register */ - REGRT1 = REG_R1 /* reserved for runtime, duffzero and duffcopy */ - REGRT2 = REG_R2 /* reserved for runtime, duffcopy */ - REGCTXT = REG_R22 /* context for closures */ - REGG = REG_R30 /* G */ - REGTMP = REG_R23 /* used by the linker */ - FREGRET = REG_F0 -) - -const ( - BIG = 32766 -) - -const ( - /* mark flags */ - FOLL = 1 << 0 - LABEL = 1 << 1 - LEAF = 1 << 2 - SYNC = 1 << 3 - BRANCH = 1 << 4 - LOAD = 1 << 5 - FCMP = 1 << 6 - NOSCHED = 1 << 7 - - NSCHED = 20 -) - -const ( - C_NONE = iota - C_REG - C_FREG - C_FCREG - C_MREG /* special processor register */ - C_HI - C_LO - C_ZCON - C_SCON /* 16 bit signed */ - C_UCON /* 32 bit signed, low 16 bits 0 */ - C_ADD0CON - C_AND0CON - C_ADDCON /* -0x8000 <= v < 0 */ - C_ANDCON /* 0 < v <= 0xFFFF */ - C_LCON /* other 32 */ - C_DCON /* other 64 (could subdivide further) */ - C_SACON /* $n(REG) where n <= int16 */ - C_SECON - C_LACON /* $n(REG) where int16 < n <= int32 */ - C_LECON - C_DACON /* $n(REG) where int32 < n */ - C_STCON /* $tlsvar */ - C_SBRA - C_LBRA - C_SAUTO - C_LAUTO - C_SEXT - C_LEXT - C_ZOREG - C_SOREG - C_LOREG - C_GOK - C_ADDR - C_TLS - C_TEXTSIZE - - C_NCLASS /* must be the last */ -) - -const ( - AABSD = obj.ABaseMIPS64 + obj.A_ARCHSPECIFIC + iota - AABSF - AABSW - AADD - AADDD - AADDF - AADDU - AADDW - AAND - ABEQ - ABFPF - ABFPT - ABGEZ - ABGEZAL - ABGTZ - ABLEZ - ABLTZ - ABLTZAL - ABNE - ABREAK - ACMPEQD - ACMPEQF - ACMPGED - ACMPGEF - ACMPGTD - ACMPGTF - ADIV - ADIVD - ADIVF - ADIVU - ADIVW - AGOK - ALUI - AMOVB - AMOVBU - AMOVD - AMOVDF - AMOVDW - AMOVF - AMOVFD - AMOVFW - AMOVH - AMOVHU - AMOVW - AMOVWD - AMOVWF - AMOVWL - AMOVWR - AMUL - AMULD - AMULF - AMULU - AMULW - ANEGD - ANEGF - ANEGW - ANOR - AOR - AREM - AREMU - ARFE - ASGT - ASGTU - ASLL - ASRA - ASRL - ASUB - ASUBD - ASUBF - ASUBU - ASUBW - ASYSCALL - ATLBP - ATLBR - ATLBWI - ATLBWR - AWORD - AXOR - - /* 64-bit */ - AMOVV - AMOVVL - AMOVVR - ASLLV - ASRAV - ASRLV - ADIVV - ADIVVU - AREMV - AREMVU - AMULV - AMULVU - AADDV - AADDVU - ASUBV - ASUBVU - - /* 64-bit FP */ - ATRUNCFV - ATRUNCDV - ATRUNCFW - ATRUNCDW - AMOVWU - AMOVFV - AMOVDV - AMOVVF - AMOVVD - - ALAST - - // aliases - AJMP = obj.AJMP - AJAL = obj.ACALL - ARET = obj.ARET -) diff --git a/vendor/github.com/google/gops/internal/obj/mips/anames.go b/vendor/github.com/google/gops/internal/obj/mips/anames.go deleted file mode 100644 index 06a366fc..00000000 --- a/vendor/github.com/google/gops/internal/obj/mips/anames.go +++ /dev/null @@ -1,113 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p mips -// Do not edit. - -package mips - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "ABSD", - "ABSF", - "ABSW", - "ADD", - "ADDD", - "ADDF", - "ADDU", - "ADDW", - "AND", - "BEQ", - "BFPF", - "BFPT", - "BGEZ", - "BGEZAL", - "BGTZ", - "BLEZ", - "BLTZ", - "BLTZAL", - "BNE", - "BREAK", - "CMPEQD", - "CMPEQF", - "CMPGED", - "CMPGEF", - "CMPGTD", - "CMPGTF", - "DIV", - "DIVD", - "DIVF", - "DIVU", - "DIVW", - "GOK", - "LUI", - "MOVB", - "MOVBU", - "MOVD", - "MOVDF", - "MOVDW", - "MOVF", - "MOVFD", - "MOVFW", - "MOVH", - "MOVHU", - "MOVW", - "MOVWD", - "MOVWF", - "MOVWL", - "MOVWR", - "MUL", - "MULD", - "MULF", - "MULU", - "MULW", - "NEGD", - "NEGF", - "NEGW", - "NOR", - "OR", - "REM", - "REMU", - "RFE", - "SGT", - "SGTU", - "SLL", - "SRA", - "SRL", - "SUB", - "SUBD", - "SUBF", - "SUBU", - "SUBW", - "SYSCALL", - "TLBP", - "TLBR", - "TLBWI", - "TLBWR", - "WORD", - "XOR", - "MOVV", - "MOVVL", - "MOVVR", - "SLLV", - "SRAV", - "SRLV", - "DIVV", - "DIVVU", - "REMV", - "REMVU", - "MULV", - "MULVU", - "ADDV", - "ADDVU", - "SUBV", - "SUBVU", - "TRUNCFV", - "TRUNCDV", - "TRUNCFW", - "TRUNCDW", - "MOVWU", - "MOVFV", - "MOVDV", - "MOVVF", - "MOVVD", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/mips/anames0.go b/vendor/github.com/google/gops/internal/obj/mips/anames0.go deleted file mode 100644 index c56d34ea..00000000 --- a/vendor/github.com/google/gops/internal/obj/mips/anames0.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 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 mips - -var cnames0 = []string{ - "NONE", - "REG", - "FREG", - "FCREG", - "MREG", - "HI", - "LO", - "ZCON", - "SCON", - "UCON", - "ADD0CON", - "AND0CON", - "ADDCON", - "ANDCON", - "LCON", - "DCON", - "SACON", - "SECON", - "LACON", - "LECON", - "DACON", - "STCON", - "SBRA", - "LBRA", - "SAUTO", - "LAUTO", - "SEXT", - "LEXT", - "ZOREG", - "SOREG", - "LOREG", - "GOK", - "ADDR", - "TLS", - "TEXTSIZE", - "NCLASS", -} diff --git a/vendor/github.com/google/gops/internal/obj/mips/asm0.go b/vendor/github.com/google/gops/internal/obj/mips/asm0.go deleted file mode 100644 index ef4ceddc..00000000 --- a/vendor/github.com/google/gops/internal/obj/mips/asm0.go +++ /dev/null @@ -1,1783 +0,0 @@ -// cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package mips - -import ( - "fmt" - "log" - "sort" - - "github.com/google/gops/internal/obj" -) - -// Instruction layout. - -const ( - funcAlign = 8 -) - -const ( - r0iszero = 1 -) - -type Optab struct { - as obj.As - a1 uint8 - a2 uint8 - a3 uint8 - type_ int8 - size int8 - param int16 -} - -var optab = []Optab{ - {obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0}, - {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0}, - - {AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0}, - {AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0}, - {AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0}, - {AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0}, - {AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0}, - - {ASUB, C_REG, C_REG, C_REG, 2, 4, 0}, - {AADD, C_REG, C_REG, C_REG, 2, 4, 0}, - {AAND, C_REG, C_REG, C_REG, 2, 4, 0}, - {ASUB, C_REG, C_NONE, C_REG, 2, 4, 0}, - {AADD, C_REG, C_NONE, C_REG, 2, 4, 0}, - {AAND, C_REG, C_NONE, C_REG, 2, 4, 0}, - - {ASLL, C_REG, C_NONE, C_REG, 9, 4, 0}, - {ASLL, C_REG, C_REG, C_REG, 9, 4, 0}, - - {AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0}, - {AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0}, - {ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0}, - {AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0}, - {AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0}, - {AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0}, - - {AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - - {AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, - - {AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, - {AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, - {AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, - {AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, - {AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB}, - {AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, - {AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, - {AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, - {AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, - {AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP}, - {AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, - {AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, - {AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, - {AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, - {AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO}, - {AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0}, - {AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0}, - {AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0}, - {AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0}, - {AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0}, - {AMOVW, C_REG, C_NONE, C_TLS, 53, 8, 0}, - {AMOVWU, C_REG, C_NONE, C_TLS, 53, 8, 0}, - {AMOVV, C_REG, C_NONE, C_TLS, 53, 8, 0}, - {AMOVB, C_REG, C_NONE, C_TLS, 53, 8, 0}, - {AMOVBU, C_REG, C_NONE, C_TLS, 53, 8, 0}, - - {AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, - {AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, - {AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, - {AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, - {AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB}, - {AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, - {AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, - {AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, - {AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, - {AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP}, - {AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, - {AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, - {AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, - {AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO}, - {AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0}, - {AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0}, - {AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0}, - {AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0}, - {AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0}, - {AMOVW, C_TLS, C_NONE, C_REG, 54, 8, 0}, - {AMOVWU, C_TLS, C_NONE, C_REG, 54, 8, 0}, - {AMOVV, C_TLS, C_NONE, C_REG, 54, 8, 0}, - {AMOVB, C_TLS, C_NONE, C_REG, 54, 8, 0}, - {AMOVBU, C_TLS, C_NONE, C_REG, 54, 8, 0}, - - {AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB}, - {AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB}, - {AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP}, - {AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP}, - {AMOVW, C_LECON, C_NONE, C_REG, 52, 12, REGSB}, - {AMOVV, C_LECON, C_NONE, C_REG, 52, 12, REGSB}, - {AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP}, - {AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP}, - {AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVW, C_STCON, C_NONE, C_REG, 55, 8, 0}, - {AMOVV, C_STCON, C_NONE, C_REG, 55, 8, 0}, - - {AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0}, - {AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0}, - {AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0}, - {AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0}, - - {AMOVW, C_HI, C_NONE, C_REG, 20, 4, 0}, - {AMOVV, C_HI, C_NONE, C_REG, 20, 4, 0}, - {AMOVW, C_LO, C_NONE, C_REG, 20, 4, 0}, - {AMOVV, C_LO, C_NONE, C_REG, 20, 4, 0}, - {AMOVW, C_REG, C_NONE, C_HI, 21, 4, 0}, - {AMOVV, C_REG, C_NONE, C_HI, 21, 4, 0}, - {AMOVW, C_REG, C_NONE, C_LO, 21, 4, 0}, - {AMOVV, C_REG, C_NONE, C_LO, 21, 4, 0}, - - {AMUL, C_REG, C_REG, C_NONE, 22, 4, 0}, - - {AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0}, - {AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0}, - {AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0}, - {AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0}, - - {AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0}, - {AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0}, - {AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0}, - {AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0}, - - {AADD, C_UCON, C_REG, C_REG, 25, 8, 0}, - {AADD, C_UCON, C_NONE, C_REG, 25, 8, 0}, - {AAND, C_UCON, C_REG, C_REG, 25, 8, 0}, - {AAND, C_UCON, C_NONE, C_REG, 25, 8, 0}, - - {AADD, C_LCON, C_NONE, C_REG, 23, 12, 0}, - {AAND, C_LCON, C_NONE, C_REG, 23, 12, 0}, - {AADD, C_LCON, C_REG, C_REG, 23, 12, 0}, - {AAND, C_LCON, C_REG, C_REG, 23, 12, 0}, - - {ASLL, C_SCON, C_REG, C_REG, 16, 4, 0}, - {ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0}, - - {ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0}, - - {ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0}, - {ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0}, - {ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0}, - {ABFPT, C_NONE, C_NONE, C_SBRA, 6, 8, 0}, - - {AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, - {AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, - - {AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO}, - {AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK}, - - {AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB}, - {AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB}, - {AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB}, - {AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP}, - {AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP}, - {AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP}, - {AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, - {AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, - {AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, - - {AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB}, - {AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB}, - {AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB}, - {AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP}, - {AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP}, - {AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP}, - {AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO}, - {AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO}, - {AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO}, - {AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0}, - {AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0}, - - {AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB}, - {AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB}, - {AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB}, - {AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP}, - {AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP}, - {AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP}, - {AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, - {AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, - {AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, - - {AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB}, - {AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB}, - {AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB}, - {AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP}, - {AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP}, - {AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP}, - {AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO}, - {AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO}, - {AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO}, - {AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0}, - {AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0}, - - {AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0}, - {AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0}, - {AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0}, - {AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0}, - - {AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0}, - {AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0}, - - {AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0}, - {AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0}, - {AMOVW, C_MREG, C_NONE, C_REG, 38, 4, 0}, - {AMOVV, C_MREG, C_NONE, C_REG, 38, 4, 0}, - - {AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0}, - - {AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0}, - {AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0}, - {AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0}, - {AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0}, - - {ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, /* really CACHE instruction */ - {ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP}, - {ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO}, - {ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0}, - - {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0}, - {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0}, - {obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0}, - {obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0}, - {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0}, - {obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP - {obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP - - {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0}, -} - -var oprange [ALAST & obj.AMask][]Optab - -var xcmp [C_NCLASS][C_NCLASS]bool - -func span0(ctxt *obj.Link, cursym *obj.LSym) { - p := cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - ctxt.Cursym = cursym - ctxt.Autosize = int32(p.To.Offset + 8) - - if oprange[AOR&obj.AMask] == nil { - buildop(ctxt) - } - - c := int64(0) - p.Pc = c - - var m int - var o *Optab - for p = p.Link; p != nil; p = p.Link { - ctxt.Curp = p - p.Pc = c - o = oplook(ctxt, p) - m = int(o.size) - if m == 0 { - if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { - ctxt.Diag("zero-width instruction\n%v", p) - } - continue - } - - c += int64(m) - } - - cursym.Size = c - - /* - * if any procedure is large enough to - * generate a large SBRA branch, then - * generate extra passes putting branches - * around jmps to fix. this is rare. - */ - bflag := 1 - - var otxt int64 - var q *obj.Prog - for bflag != 0 { - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f span1\n", obj.Cputime()) - } - bflag = 0 - c = 0 - for p = cursym.Text.Link; p != nil; p = p.Link { - p.Pc = c - o = oplook(ctxt, p) - - // very large conditional branches - if o.type_ == 6 && p.Pcond != nil { - otxt = p.Pcond.Pc - c - if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 { - q = ctxt.NewProg() - q.Link = p.Link - p.Link = q - q.As = AJMP - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.Pcond = p.Pcond - p.Pcond = q - q = ctxt.NewProg() - q.Link = p.Link - p.Link = q - q.As = AJMP - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.Pcond = q.Link.Link - - addnop(ctxt, p.Link) - addnop(ctxt, p) - bflag = 1 - } - } - - m = int(o.size) - if m == 0 { - if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { - ctxt.Diag("zero-width instruction\n%v", p) - } - continue - } - - c += int64(m) - } - - cursym.Size = c - } - - c += -c & (funcAlign - 1) - cursym.Size = c - - /* - * lay out the code, emitting code and data relocations. - */ - - cursym.Grow(cursym.Size) - - bp := cursym.P - var i int32 - var out [4]uint32 - for p := cursym.Text.Link; p != nil; p = p.Link { - ctxt.Pc = p.Pc - ctxt.Curp = p - o = oplook(ctxt, p) - if int(o.size) > 4*len(out) { - log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p) - } - asmout(ctxt, p, o, out[:]) - for i = 0; i < int32(o.size/4); i++ { - ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) - bp = bp[4:] - } - } -} - -func isint32(v int64) bool { - return int64(int32(v)) == v -} - -func isuint32(v uint64) bool { - return uint64(uint32(v)) == v -} - -func aclass(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return C_NONE - - case obj.TYPE_REG: - if REG_R0 <= a.Reg && a.Reg <= REG_R31 { - return C_REG - } - if REG_F0 <= a.Reg && a.Reg <= REG_F31 { - return C_FREG - } - if REG_M0 <= a.Reg && a.Reg <= REG_M31 { - return C_MREG - } - if REG_FCR0 <= a.Reg && a.Reg <= REG_FCR31 { - return C_FCREG - } - if a.Reg == REG_LO { - return C_LO - } - if a.Reg == REG_HI { - return C_HI - } - return C_GOK - - case obj.TYPE_MEM: - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_STATIC: - if a.Sym == nil { - break - } - ctxt.Instoffset = a.Offset - if a.Sym != nil { // use relocation - if a.Sym.Type == obj.STLSBSS { - return C_TLS - } - return C_ADDR - } - return C_LEXT - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SAUTO - } - return C_LAUTO - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SAUTO - } - return C_LAUTO - - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if ctxt.Instoffset == 0 { - return C_ZOREG - } - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SOREG - } - return C_LOREG - } - - return C_GOK - - case obj.TYPE_TEXTSIZE: - return C_TEXTSIZE - - case obj.TYPE_CONST, - obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if a.Reg != 0 { - if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { - return C_SACON - } - if isint32(ctxt.Instoffset) { - return C_LACON - } - return C_DACON - } - - goto consize - - case obj.NAME_EXTERN, - obj.NAME_STATIC: - s := a.Sym - if s == nil { - break - } - if s.Type == obj.SCONST { - ctxt.Instoffset = a.Offset - goto consize - } - - ctxt.Instoffset = a.Offset - if s.Type == obj.STLSBSS { - return C_STCON // address of TLS variable - } - return C_LECON - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SACON - } - return C_LACON - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SACON - } - return C_LACON - } - - return C_GOK - - consize: - if ctxt.Instoffset >= 0 { - if ctxt.Instoffset == 0 { - return C_ZCON - } - if ctxt.Instoffset <= 0x7fff { - return C_SCON - } - if ctxt.Instoffset <= 0xffff { - return C_ANDCON - } - if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */ - return C_UCON - } - if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) { - return C_LCON - } - return C_LCON // C_DCON - } - - if ctxt.Instoffset >= -0x8000 { - return C_ADDCON - } - if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) { - return C_UCON - } - if isint32(ctxt.Instoffset) { - return C_LCON - } - return C_LCON // C_DCON - - case obj.TYPE_BRANCH: - return C_SBRA - } - - return C_GOK -} - -func prasm(p *obj.Prog) { - fmt.Printf("%v\n", p) -} - -func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { - if oprange[AOR&obj.AMask] == nil { - buildop(ctxt) - } - - a1 := int(p.Optab) - if a1 != 0 { - return &optab[a1-1] - } - a1 = int(p.From.Class) - if a1 == 0 { - a1 = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(a1) - } - - a1-- - a3 := int(p.To.Class) - if a3 == 0 { - a3 = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(a3) - } - - a3-- - a2 := C_NONE - if p.Reg != 0 { - a2 = C_REG - } - - //print("oplook %P %d %d %d\n", p, a1, a2, a3); - - ops := oprange[p.As&obj.AMask] - c1 := &xcmp[a1] - c3 := &xcmp[a3] - for i := range ops { - op := &ops[i] - if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] { - p.Optab = uint16(cap(optab) - cap(ops) + i + 1) - return op - } - } - - ctxt.Diag("illegal combination %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3)) - prasm(p) - if ops == nil { - ops = optab - } - return &ops[0] -} - -func cmp(a int, b int) bool { - if a == b { - return true - } - switch a { - case C_LCON: - if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON { - return true - } - - case C_ADD0CON: - if b == C_ADDCON { - return true - } - fallthrough - - case C_ADDCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_AND0CON: - if b == C_ANDCON { - return true - } - fallthrough - - case C_ANDCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_UCON: - if b == C_ZCON { - return true - } - - case C_SCON: - if b == C_ZCON { - return true - } - - case C_LACON: - if b == C_SACON { - return true - } - - case C_LBRA: - if b == C_SBRA { - return true - } - - case C_LEXT: - if b == C_SEXT { - return true - } - - case C_LAUTO: - if b == C_SAUTO { - return true - } - - case C_REG: - if b == C_ZCON { - return r0iszero != 0 /*TypeKind(100016)*/ - } - - case C_LOREG: - if b == C_ZOREG || b == C_SOREG { - return true - } - - case C_SOREG: - if b == C_ZOREG { - return true - } - } - - return false -} - -type ocmp []Optab - -func (x ocmp) Len() int { - return len(x) -} - -func (x ocmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x ocmp) Less(i, j int) bool { - p1 := &x[i] - p2 := &x[j] - n := int(p1.as) - int(p2.as) - if n != 0 { - return n < 0 - } - n = int(p1.a1) - int(p2.a1) - if n != 0 { - return n < 0 - } - n = int(p1.a2) - int(p2.a2) - if n != 0 { - return n < 0 - } - n = int(p1.a3) - int(p2.a3) - if n != 0 { - return n < 0 - } - return false -} - -func opset(a, b0 obj.As) { - oprange[a&obj.AMask] = oprange[b0] -} - -func buildop(ctxt *obj.Link) { - var n int - - for i := 0; i < C_NCLASS; i++ { - for n = 0; n < C_NCLASS; n++ { - if cmp(n, i) { - xcmp[i][n] = true - } - } - } - for n = 0; optab[n].as != obj.AXXX; n++ { - } - sort.Sort(ocmp(optab[:n])) - for i := 0; i < n; i++ { - r := optab[i].as - r0 := r & obj.AMask - start := i - for optab[i].as == r { - i++ - } - oprange[r0] = optab[start:i] - i-- - - switch r { - default: - ctxt.Diag("unknown op in build: %v", r) - log.Fatalf("bad code") - - case AABSF: - opset(AMOVFD, r0) - opset(AMOVDF, r0) - opset(AMOVWF, r0) - opset(AMOVFW, r0) - opset(AMOVWD, r0) - opset(AMOVDW, r0) - opset(ANEGF, r0) - opset(ANEGD, r0) - opset(AABSD, r0) - opset(ATRUNCDW, r0) - opset(ATRUNCFW, r0) - opset(ATRUNCDV, r0) - opset(ATRUNCFV, r0) - opset(AMOVVF, r0) - opset(AMOVFV, r0) - opset(AMOVVD, r0) - opset(AMOVDV, r0) - - case AADD: - opset(ASGT, r0) - opset(ASGTU, r0) - opset(AADDU, r0) - opset(AADDV, r0) - opset(AADDVU, r0) - - case AADDF: - opset(ADIVF, r0) - opset(ADIVD, r0) - opset(AMULF, r0) - opset(AMULD, r0) - opset(ASUBF, r0) - opset(ASUBD, r0) - opset(AADDD, r0) - - case AAND: - opset(AOR, r0) - opset(AXOR, r0) - - case ABEQ: - opset(ABNE, r0) - - case ABLEZ: - opset(ABGEZ, r0) - opset(ABGEZAL, r0) - opset(ABLTZ, r0) - opset(ABLTZAL, r0) - opset(ABGTZ, r0) - - case AMOVB: - opset(AMOVH, r0) - - case AMOVBU: - opset(AMOVHU, r0) - - case AMUL: - opset(AREM, r0) - opset(AREMU, r0) - opset(ADIVU, r0) - opset(AMULU, r0) - opset(ADIV, r0) - opset(ADIVV, r0) - opset(ADIVVU, r0) - opset(AMULV, r0) - opset(AMULVU, r0) - opset(AREMV, r0) - opset(AREMVU, r0) - - case ASLL: - opset(ASRL, r0) - opset(ASRA, r0) - opset(ASLLV, r0) - opset(ASRAV, r0) - opset(ASRLV, r0) - - case ASUB: - opset(ASUBU, r0) - opset(ASUBV, r0) - opset(ASUBVU, r0) - opset(ANOR, r0) - - case ASYSCALL: - opset(ATLBP, r0) - opset(ATLBR, r0) - opset(ATLBWI, r0) - opset(ATLBWR, r0) - - case ACMPEQF: - opset(ACMPGTF, r0) - opset(ACMPGTD, r0) - opset(ACMPGEF, r0) - opset(ACMPGED, r0) - opset(ACMPEQD, r0) - - case ABFPT: - opset(ABFPF, r0) - - case AMOVWL: - opset(AMOVWR, r0) - opset(AMOVVR, r0) - opset(AMOVVL, r0) - - case AMOVW, - AMOVD, - AMOVF, - AMOVV, - ABREAK, - ARFE, - AJAL, - AJMP, - AMOVWU, - AWORD, - obj.ANOP, - obj.ATEXT, - obj.AUNDEF, - obj.AUSEFIELD, - obj.AFUNCDATA, - obj.APCDATA, - obj.ADUFFZERO, - obj.ADUFFCOPY: - break - } - } -} - -func OP(x uint32, y uint32) uint32 { - return x<<3 | y<<0 -} - -func SP(x uint32, y uint32) uint32 { - return x<<29 | y<<26 -} - -func BCOND(x uint32, y uint32) uint32 { - return x<<19 | y<<16 -} - -func MMU(x uint32, y uint32) uint32 { - return SP(2, 0) | 16<<21 | x<<3 | y<<0 -} - -func FPF(x uint32, y uint32) uint32 { - return SP(2, 1) | 16<<21 | x<<3 | y<<0 -} - -func FPD(x uint32, y uint32) uint32 { - return SP(2, 1) | 17<<21 | x<<3 | y<<0 -} - -func FPW(x uint32, y uint32) uint32 { - return SP(2, 1) | 20<<21 | x<<3 | y<<0 -} - -func FPV(x uint32, y uint32) uint32 { - return SP(2, 1) | 21<<21 | x<<3 | y<<0 -} - -func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 { - return op | (r1&31)<<16 | (r2&31)<<21 | (r3&31)<<11 -} - -func OP_IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { - return op | i&0xFFFF | (r2&31)<<21 | (r3&31)<<16 -} - -func OP_SRR(op uint32, s uint32, r2 uint32, r3 uint32) uint32 { - return op | (s&31)<<6 | (r2&31)<<16 | (r3&31)<<11 -} - -func OP_FRRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 { - return op | (r1&31)<<16 | (r2&31)<<11 | (r3&31)<<6 -} - -func OP_JMP(op uint32, i uint32) uint32 { - return op | i&0x3FFFFFF -} - -func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { - o1 := uint32(0) - o2 := uint32(0) - o3 := uint32(0) - o4 := uint32(0) - - switch o.type_ { - default: - ctxt.Diag("unknown type %d %v", o.type_) - prasm(p) - - case 0: /* pseudo ops */ - break - - case 1: /* mov r1,r2 ==> OR r1,r0,r2 */ - a := AOR - if p.As == AMOVW { - a = AADDU // sign-extended to high 32 bits - } - o1 = OP_RRR(oprrr(ctxt, a), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg)) - - case 2: /* add/sub r1,[r2],r3 */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = OP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg)) - - case 3: /* mov $soreg, r ==> or/add $i,o,r */ - v := regoff(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - a := AADDVU - if o.a1 == C_ANDCON { - a = AOR - } - - o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg)) - - case 4: /* add $scon,[r1],r2 */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - - o1 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.To.Reg)) - - case 5: /* syscall */ - o1 = oprrr(ctxt, p.As) - - case 6: /* beq r1,[r2],sbra */ - v := int32(0) - if p.Pcond == nil { - v = int32(-4) >> 2 - } else { - v = int32(p.Pcond.Pc-p.Pc-4) >> 2 - } - if (v<<16)>>16 != v { - ctxt.Diag("short branch too far\n%v", p) - } - o1 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(p.From.Reg), uint32(p.Reg)) - // for ABFPT and ABFPF only: always fill delay slot with 0 - // see comments in func preprocess for details. - o2 = 0 - - case 7: /* mov r, soreg ==> sw o(r) */ - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - v := regoff(ctxt, &p.To) - o1 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.From.Reg)) - - case 8: /* mov soreg, r ==> lw o(r) */ - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - v := regoff(ctxt, &p.From) - o1 = OP_IRR(opirr(ctxt, -p.As), uint32(v), uint32(r), uint32(p.To.Reg)) - - case 9: /* sll r1,[r2],r3 */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = OP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg)) - - case 10: /* add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2 */ - v := regoff(ctxt, &p.From) - a := AOR - if v < 0 { - a = AADDU - } - o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP)) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o2 = OP_RRR(oprrr(ctxt, p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) - - case 11: /* jmp lbra */ - v := int32(0) - if aclass(ctxt, &p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP { - // use PC-relative branch for short branches - // BEQ R0, R0, sbra - if p.Pcond == nil { - v = int32(-4) >> 2 - } else { - v = int32(p.Pcond.Pc-p.Pc-4) >> 2 - } - if (v<<16)>>16 == v { - o1 = OP_IRR(opirr(ctxt, ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO)) - break - } - } - if p.Pcond == nil { - v = int32(p.Pc) >> 2 - } else { - v = int32(p.Pcond.Pc) >> 2 - } - o1 = OP_JMP(opirr(ctxt, p.As), uint32(v)) - if p.To.Sym == nil { - p.To.Sym = ctxt.Cursym.Text.From.Sym - p.To.Offset = p.Pcond.Pc - } - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - if p.As == AJAL { - rel.Type = obj.R_CALLMIPS - } else { - rel.Type = obj.R_JMPMIPS - } - - case 12: /* movbs r,r */ - v := 16 - if p.As == AMOVB { - v = 24 - } - o1 = OP_SRR(opirr(ctxt, ASLL), uint32(v), uint32(p.From.Reg), uint32(p.To.Reg)) - o2 = OP_SRR(opirr(ctxt, ASRA), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) - - case 13: /* movbu r,r */ - if p.As == AMOVBU { - o1 = OP_IRR(opirr(ctxt, AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg)) - } else { - o1 = OP_IRR(opirr(ctxt, AAND), uint32(0xffff), uint32(p.From.Reg), uint32(p.To.Reg)) - } - - case 14: /* movwu r,r */ - o1 = OP_SRR(opirr(ctxt, -ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg)) - o2 = OP_SRR(opirr(ctxt, -ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) - - case 16: /* sll $c,[r1],r2 */ - v := regoff(ctxt, &p.From) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - - /* OP_SRR will use only the low 5 bits of the shift value */ - if v >= 32 && vshift(p.As) { - o1 = OP_SRR(opirr(ctxt, -p.As), uint32(v-32), uint32(r), uint32(p.To.Reg)) - } else { - o1 = OP_SRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.To.Reg)) - } - - case 18: /* jmp [r1],0(r2) */ - r := int(p.Reg) - if r == 0 { - r = int(o.param) - } - o1 = OP_RRR(oprrr(ctxt, p.As), uint32(0), uint32(p.To.Reg), uint32(r)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 0 - rel.Type = obj.R_CALLIND - - case 19: /* mov $lcon,r ==> lu+or */ - v := regoff(ctxt, &p.From) - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg)) - o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) - - case 20: /* mov lo/hi,r */ - a := OP(2, 0) /* mfhi */ - if p.From.Reg == REG_LO { - a = OP(2, 2) /* mflo */ - } - o1 = OP_RRR(a, uint32(REGZERO), uint32(REGZERO), uint32(p.To.Reg)) - - case 21: /* mov r,lo/hi */ - a := OP(2, 1) /* mthi */ - if p.To.Reg == REG_LO { - a = OP(2, 3) /* mtlo */ - } - o1 = OP_RRR(a, uint32(REGZERO), uint32(p.From.Reg), uint32(REGZERO)) - - case 22: /* mul r1,r2 */ - o1 = OP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(REGZERO)) - - case 23: /* add $lcon,r1,r2 ==> lu+or+add */ - v := regoff(ctxt, &p.From) - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) - o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o3 = OP_RRR(oprrr(ctxt, p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) - - case 24: /* mov $ucon,r ==> lu r */ - v := regoff(ctxt, &p.From) - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg)) - - case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */ - v := regoff(ctxt, &p.From) - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o2 = OP_RRR(oprrr(ctxt, p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) - - case 26: /* mov $lsext/auto/oreg,r ==> lu+or+add */ - v := regoff(ctxt, &p.From) - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) - o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) - - case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */ - v := regoff(ctxt, &p.From) - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - a := -AMOVF - if p.As == AMOVD { - a = -AMOVD - } - switch o.size { - case 12: - o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) - o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.To.Reg)) - - case 4: - o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg)) - } - - case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */ - v := regoff(ctxt, &p.To) - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - a := AMOVF - if p.As == AMOVD { - a = AMOVD - } - switch o.size { - case 12: - o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) - o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.From.Reg)) - - case 4: - o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.From.Reg)) - } - - case 30: /* movw r,fr */ - a := SP(2, 1) | (4 << 21) /* mtc1 */ - o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) - - case 31: /* movw fr,r */ - a := SP(2, 1) | (0 << 21) /* mtc1 */ - o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) - - case 32: /* fadd fr1,[fr2],fr3 */ - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 = OP_FRRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg)) - - case 33: /* fabs fr1, fr3 */ - o1 = OP_FRRR(oprrr(ctxt, p.As), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg)) - - case 34: /* mov $con,fr ==> or/add $i,t; mov t,fr */ - v := regoff(ctxt, &p.From) - a := AADDU - if o.a1 == C_ANDCON { - a = AOR - } - o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP)) - o2 = OP_RRR(SP(2, 1)|(4<<21), uint32(REGTMP), uint32(0), uint32(p.To.Reg)) /* mtc1 */ - - case 35: /* mov r,lext/auto/oreg ==> sw o(REGTMP) */ - v := regoff(ctxt, &p.To) - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) - o3 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg)) - - case 36: /* mov lext/auto/oreg,r ==> lw o(REGTMP) */ - v := regoff(ctxt, &p.From) - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP)) - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) - o3 = OP_IRR(opirr(ctxt, -p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg)) - - case 37: /* movw r,mr */ - a := SP(2, 0) | (4 << 21) /* mtc0 */ - if p.As == AMOVV { - a = SP(2, 0) | (5 << 21) /* dmtc0 */ - } - o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) - - case 38: /* movw mr,r */ - a := SP(2, 0) | (0 << 21) /* mfc0 */ - if p.As == AMOVV { - a = SP(2, 0) | (1 << 21) /* dmfc0 */ - } - o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) - - case 40: /* word */ - o1 = uint32(regoff(ctxt, &p.From)) - - case 41: /* movw f,fcr */ - o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(REGZERO), uint32(0), uint32(p.To.Reg)) /* mfcc1 */ - o2 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */ - - case 42: /* movw fcr,r */ - o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */ - - case 47: /* movv r,fr */ - a := SP(2, 1) | (5 << 21) /* dmtc1 */ - o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) - - case 48: /* movv fr,r */ - a := SP(2, 1) | (1 << 21) /* dmtc1 */ - o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) - - case 49: /* undef */ - o1 = 52 /* trap -- teq r0, r0 */ - - /* relocation operations */ - case 50: /* mov r,addr ==> lu + add REGSB, REGTMP + sw o(REGTMP) */ - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - rel.Type = obj.R_ADDRMIPSU - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP)) - o3 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) - rel2 := obj.Addrel(ctxt.Cursym) - rel2.Off = int32(ctxt.Pc + 8) - rel2.Siz = 4 - rel2.Sym = p.To.Sym - rel2.Add = p.To.Offset - rel2.Type = obj.R_ADDRMIPS - - case 51: /* mov addr,r ==> lu + add REGSB, REGTMP + lw o(REGTMP) */ - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDRMIPSU - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP)) - o3 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) - rel2 := obj.Addrel(ctxt.Cursym) - rel2.Off = int32(ctxt.Pc + 8) - rel2.Siz = 4 - rel2.Sym = p.From.Sym - rel2.Add = p.From.Offset - rel2.Type = obj.R_ADDRMIPS - - case 52: /* mov $lext, r ==> lu + add REGSB, r + add */ - o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(p.To.Reg)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDRMIPSU - o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(p.To.Reg), uint32(p.To.Reg)) - o3 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) - rel2 := obj.Addrel(ctxt.Cursym) - rel2.Off = int32(ctxt.Pc + 8) - rel2.Siz = 4 - rel2.Sym = p.From.Sym - rel2.Add = p.From.Offset - rel2.Type = obj.R_ADDRMIPS - - case 53: /* mov r, tlsvar ==> rdhwr + sw o(r3) */ - // clobbers R3 ! - // load thread pointer with RDHWR, R3 is used for fast kernel emulation on Linux - o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 - o2 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REG_R3), uint32(p.From.Reg)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + 4) - rel.Siz = 4 - rel.Sym = p.To.Sym - rel.Add = p.To.Offset - rel.Type = obj.R_ADDRMIPSTLS - - case 54: /* mov tlsvar, r ==> rdhwr + lw o(r3) */ - // clobbers R3 ! - o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 - o2 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REG_R3), uint32(p.To.Reg)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + 4) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDRMIPSTLS - - case 55: /* mov $tlsvar, r ==> rdhwr + add */ - // clobbers R3 ! - o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 - o2 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(REG_R3), uint32(p.To.Reg)) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + 4) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDRMIPSTLS - } - - out[0] = o1 - out[1] = o2 - out[2] = o3 - out[3] = o4 - return -} - -func vregoff(ctxt *obj.Link, a *obj.Addr) int64 { - ctxt.Instoffset = 0 - aclass(ctxt, a) - return ctxt.Instoffset -} - -func regoff(ctxt *obj.Link, a *obj.Addr) int32 { - return int32(vregoff(ctxt, a)) -} - -func oprrr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AADD: - return OP(4, 0) - case AADDU: - return OP(4, 1) - case ASGT: - return OP(5, 2) - case ASGTU: - return OP(5, 3) - case AAND: - return OP(4, 4) - case AOR: - return OP(4, 5) - case AXOR: - return OP(4, 6) - case ASUB: - return OP(4, 2) - case ASUBU: - return OP(4, 3) - case ANOR: - return OP(4, 7) - case ASLL: - return OP(0, 4) - case ASRL: - return OP(0, 6) - case ASRA: - return OP(0, 7) - case ASLLV: - return OP(2, 4) - case ASRLV: - return OP(2, 6) - case ASRAV: - return OP(2, 7) - case AADDV: - return OP(5, 4) - case AADDVU: - return OP(5, 5) - case ASUBV: - return OP(5, 6) - case ASUBVU: - return OP(5, 7) - case AREM, - ADIV: - return OP(3, 2) - case AREMU, - ADIVU: - return OP(3, 3) - case AMUL: - return OP(3, 0) - case AMULU: - return OP(3, 1) - case AREMV, - ADIVV: - return OP(3, 6) - case AREMVU, - ADIVVU: - return OP(3, 7) - case AMULV: - return OP(3, 4) - case AMULVU: - return OP(3, 5) - - case AJMP: - return OP(1, 0) - case AJAL: - return OP(1, 1) - - case ABREAK: - return OP(1, 5) - case ASYSCALL: - return OP(1, 4) - case ATLBP: - return MMU(1, 0) - case ATLBR: - return MMU(0, 1) - case ATLBWI: - return MMU(0, 2) - case ATLBWR: - return MMU(0, 6) - case ARFE: - return MMU(2, 0) - - case ADIVF: - return FPF(0, 3) - case ADIVD: - return FPD(0, 3) - case AMULF: - return FPF(0, 2) - case AMULD: - return FPD(0, 2) - case ASUBF: - return FPF(0, 1) - case ASUBD: - return FPD(0, 1) - case AADDF: - return FPF(0, 0) - case AADDD: - return FPD(0, 0) - case ATRUNCFV: - return FPF(1, 1) - case ATRUNCDV: - return FPD(1, 1) - case ATRUNCFW: - return FPF(1, 5) - case ATRUNCDW: - return FPD(1, 5) - case AMOVFV: - return FPF(4, 5) - case AMOVDV: - return FPD(4, 5) - case AMOVVF: - return FPV(4, 0) - case AMOVVD: - return FPV(4, 1) - case AMOVFW: - return FPF(4, 4) - case AMOVDW: - return FPD(4, 4) - case AMOVWF: - return FPW(4, 0) - case AMOVDF: - return FPD(4, 0) - case AMOVWD: - return FPW(4, 1) - case AMOVFD: - return FPF(4, 1) - case AABSF: - return FPF(0, 5) - case AABSD: - return FPD(0, 5) - case AMOVF: - return FPF(0, 6) - case AMOVD: - return FPD(0, 6) - case ANEGF: - return FPF(0, 7) - case ANEGD: - return FPD(0, 7) - case ACMPEQF: - return FPF(6, 2) - case ACMPEQD: - return FPD(6, 2) - case ACMPGTF: - return FPF(7, 4) - case ACMPGTD: - return FPD(7, 4) - case ACMPGEF: - return FPF(7, 6) - case ACMPGED: - return FPD(7, 6) - } - - if a < 0 { - ctxt.Diag("bad rrr opcode -%v", -a) - } else { - ctxt.Diag("bad rrr opcode %v", a) - } - return 0 -} - -func opirr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AADD: - return SP(1, 0) - case AADDU: - return SP(1, 1) - case ASGT: - return SP(1, 2) - case ASGTU: - return SP(1, 3) - case AAND: - return SP(1, 4) - case AOR: - return SP(1, 5) - case AXOR: - return SP(1, 6) - case ALUI: - return SP(1, 7) - case ASLL: - return OP(0, 0) - case ASRL: - return OP(0, 2) - case ASRA: - return OP(0, 3) - case AADDV: - return SP(3, 0) - case AADDVU: - return SP(3, 1) - - case AJMP: - return SP(0, 2) - case AJAL, - obj.ADUFFZERO, - obj.ADUFFCOPY: - return SP(0, 3) - case ABEQ: - return SP(0, 4) - case -ABEQ: - return SP(2, 4) /* likely */ - case ABNE: - return SP(0, 5) - case -ABNE: - return SP(2, 5) /* likely */ - case ABGEZ: - return SP(0, 1) | BCOND(0, 1) - case -ABGEZ: - return SP(0, 1) | BCOND(0, 3) /* likely */ - case ABGEZAL: - return SP(0, 1) | BCOND(2, 1) - case -ABGEZAL: - return SP(0, 1) | BCOND(2, 3) /* likely */ - case ABGTZ: - return SP(0, 7) - case -ABGTZ: - return SP(2, 7) /* likely */ - case ABLEZ: - return SP(0, 6) - case -ABLEZ: - return SP(2, 6) /* likely */ - case ABLTZ: - return SP(0, 1) | BCOND(0, 0) - case -ABLTZ: - return SP(0, 1) | BCOND(0, 2) /* likely */ - case ABLTZAL: - return SP(0, 1) | BCOND(2, 0) - case -ABLTZAL: - return SP(0, 1) | BCOND(2, 2) /* likely */ - case ABFPT: - return SP(2, 1) | (257 << 16) - case -ABFPT: - return SP(2, 1) | (259 << 16) /* likely */ - case ABFPF: - return SP(2, 1) | (256 << 16) - case -ABFPF: - return SP(2, 1) | (258 << 16) /* likely */ - - case AMOVB, - AMOVBU: - return SP(5, 0) - case AMOVH, - AMOVHU: - return SP(5, 1) - case AMOVW, - AMOVWU: - return SP(5, 3) - case AMOVV: - return SP(7, 7) - case AMOVF: - return SP(7, 1) - case AMOVD: - return SP(7, 5) - case AMOVWL: - return SP(5, 2) - case AMOVWR: - return SP(5, 6) - case AMOVVL: - return SP(5, 4) - case AMOVVR: - return SP(5, 5) - - case ABREAK: - return SP(5, 7) - - case -AMOVWL: - return SP(4, 2) - case -AMOVWR: - return SP(4, 6) - case -AMOVVL: - return SP(3, 2) - case -AMOVVR: - return SP(3, 3) - case -AMOVB: - return SP(4, 0) - case -AMOVBU: - return SP(4, 4) - case -AMOVH: - return SP(4, 1) - case -AMOVHU: - return SP(4, 5) - case -AMOVW: - return SP(4, 3) - case -AMOVWU: - return SP(4, 7) - case -AMOVV: - return SP(6, 7) - case -AMOVF: - return SP(6, 1) - case -AMOVD: - return SP(6, 5) - - case ASLLV: - return OP(7, 0) - case ASRLV: - return OP(7, 2) - case ASRAV: - return OP(7, 3) - case -ASLLV: - return OP(7, 4) - case -ASRLV: - return OP(7, 6) - case -ASRAV: - return OP(7, 7) - } - - if a < 0 { - ctxt.Diag("bad irr opcode -%v", -a) - } else { - ctxt.Diag("bad irr opcode %v", a) - } - return 0 -} - -func vshift(a obj.As) bool { - switch a { - case ASLLV, - ASRLV, - ASRAV: - return true - } - return false -} diff --git a/vendor/github.com/google/gops/internal/obj/mips/list0.go b/vendor/github.com/google/gops/internal/obj/mips/list0.go deleted file mode 100644 index ac11abf6..00000000 --- a/vendor/github.com/google/gops/internal/obj/mips/list0.go +++ /dev/null @@ -1,85 +0,0 @@ -// cmd/9l/list.c from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package mips - -import ( - "fmt" - - "github.com/google/gops/internal/obj" -) - -func init() { - obj.RegisterRegister(obj.RBaseMIPS64, REG_LAST&^1023+1024, Rconv) - obj.RegisterOpcode(obj.ABaseMIPS64, Anames) -} - -func Rconv(r int) string { - if r == 0 { - return "NONE" - } - if r == REGG { - // Special case. - return "g" - } - if r == REGSB { - // Special case. - return "RSB" - } - if REG_R0 <= r && r <= REG_R31 { - return fmt.Sprintf("R%d", r-REG_R0) - } - if REG_F0 <= r && r <= REG_F31 { - return fmt.Sprintf("F%d", r-REG_F0) - } - if REG_M0 <= r && r <= REG_M31 { - return fmt.Sprintf("M%d", r-REG_M0) - } - if REG_FCR0 <= r && r <= REG_FCR31 { - return fmt.Sprintf("FCR%d", r-REG_FCR0) - } - if r == REG_HI { - return "HI" - } - if r == REG_LO { - return "LO" - } - - return fmt.Sprintf("Rgok(%d)", r-obj.RBaseMIPS64) -} - -func DRconv(a int) string { - s := "C_??" - if a >= C_NONE && a <= C_NCLASS { - s = cnames0[a] - } - var fp string - fp += s - return fp -} diff --git a/vendor/github.com/google/gops/internal/obj/mips/obj0.go b/vendor/github.com/google/gops/internal/obj/mips/obj0.go deleted file mode 100644 index d2895395..00000000 --- a/vendor/github.com/google/gops/internal/obj/mips/obj0.go +++ /dev/null @@ -1,1497 +0,0 @@ -// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package mips - -import ( - "fmt" - "math" - - "github.com/google/gops/internal/obj" - "github.com/google/gops/internal/sys" -) - -func progedit(ctxt *obj.Link, p *obj.Prog) { - p.From.Class = 0 - p.To.Class = 0 - - // Rewrite JMP/JAL to symbol as TYPE_BRANCH. - switch p.As { - case AJMP, - AJAL, - ARET, - obj.ADUFFZERO, - obj.ADUFFCOPY: - if p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - } - - // Rewrite float constants to values stored in memory. - switch p.As { - case AMOVF: - if p.From.Type == obj.TYPE_FCONST { - f32 := float32(p.From.Val.(float64)) - i32 := math.Float32bits(f32) - if i32 == 0 { - p.As = AMOVV - p.From.Type = obj.TYPE_REG - p.From.Reg = REGZERO - break - } - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 4 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - case AMOVD: - if p.From.Type == obj.TYPE_FCONST { - i64 := math.Float64bits(p.From.Val.(float64)) - if i64 == 0 { - p.As = AMOVV - p.From.Type = obj.TYPE_REG - p.From.Reg = REGZERO - break - } - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - // Put >32-bit constants in memory and load them - case AMOVV: - if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset { - literal := fmt.Sprintf("$i64.%016x", uint64(p.From.Offset)) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - } - - // Rewrite SUB constants into ADD. - switch p.As { - case ASUB: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADD - } - - case ASUBU: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADDU - } - - case ASUBV: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADDV - } - - case ASUBVU: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADDVU - } - } -} - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - // TODO(minux): add morestack short-cuts with small fixed frame-size. - ctxt.Cursym = cursym - - // a switch for enabling/disabling instruction scheduling - nosched := true - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - p := cursym.Text - textstksiz := p.To.Offset - - cursym.Args = p.To.Val.(int32) - cursym.Locals = int32(textstksiz) - - /* - * find leaf subroutines - * strip NOPs - * expand RET - * expand BECOME pseudo - */ - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f noops\n", obj.Cputime()) - } - - var q *obj.Prog - var q1 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - switch p.As { - /* too hard, just leave alone */ - case obj.ATEXT: - q = p - - p.Mark |= LABEL | LEAF | SYNC - if p.Link != nil { - p.Link.Mark |= LABEL - } - - /* too hard, just leave alone */ - case AMOVW, - AMOVV: - q = p - if p.To.Type == obj.TYPE_REG && p.To.Reg >= REG_SPECIAL { - p.Mark |= LABEL | SYNC - break - } - if p.From.Type == obj.TYPE_REG && p.From.Reg >= REG_SPECIAL { - p.Mark |= LABEL | SYNC - } - - /* too hard, just leave alone */ - case ASYSCALL, - AWORD, - ATLBWR, - ATLBWI, - ATLBP, - ATLBR: - q = p - p.Mark |= LABEL | SYNC - - case ANOR: - q = p - if p.To.Type == obj.TYPE_REG { - if p.To.Reg == REGZERO { - p.Mark |= LABEL | SYNC - } - } - - case ABGEZAL, - ABLTZAL, - AJAL, - obj.ADUFFZERO, - obj.ADUFFCOPY: - cursym.Text.Mark &^= LEAF - fallthrough - - case AJMP, - ABEQ, - ABGEZ, - ABGTZ, - ABLEZ, - ABLTZ, - ABNE, - ABFPT, ABFPF: - if p.As == ABFPT || p.As == ABFPF { - // We don't treat ABFPT and ABFPF as branches here, - // so that we will always fill nop (0x0) in their - // delay slot during assembly. - // This is to workaround a kernel FPU emulator bug - // where it uses the user stack to simulate the - // instruction in the delay slot if it's not 0x0, - // and somehow that leads to SIGSEGV when the kernel - // jump to the stack. - p.Mark |= SYNC - } else { - p.Mark |= BRANCH - } - q = p - q1 = p.Pcond - if q1 != nil { - for q1.As == obj.ANOP { - q1 = q1.Link - p.Pcond = q1 - } - - if q1.Mark&LEAF == 0 { - q1.Mark |= LABEL - } - } - //else { - // p.Mark |= LABEL - //} - q1 = p.Link - if q1 != nil { - q1.Mark |= LABEL - } - continue - - case ARET: - q = p - if p.Link != nil { - p.Link.Mark |= LABEL - } - continue - - case obj.ANOP: - q1 = p.Link - q.Link = q1 /* q is non-nop */ - q1.Mark |= p.Mark - continue - - default: - q = p - continue - } - } - - autosize := int32(0) - var p1 *obj.Prog - var p2 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - o := p.As - switch o { - case obj.ATEXT: - autosize = int32(textstksiz + 8) - if (p.Mark&LEAF != 0) && autosize <= 8 { - autosize = 0 - } else if autosize&4 != 0 { - autosize += 4 - } - p.To.Offset = int64(autosize) - 8 - - if p.From3.Offset&obj.NOSPLIT == 0 { - p = stacksplit(ctxt, p, autosize) // emit split check - } - - q = p - - if autosize != 0 { - // Make sure to save link register for non-empty frame, even if - // it is a leaf function, so that traceback works. - // Store link register before decrement SP, so if a signal comes - // during the execution of the function prologue, the traceback - // code will not see a half-updated stack frame. - q = obj.Appendp(ctxt, q) - q.As = AMOVV - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REGLINK - q.To.Type = obj.TYPE_MEM - q.To.Offset = int64(-autosize) - q.To.Reg = REGSP - - q = obj.Appendp(ctxt, q) - q.As = AADDV - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(-autosize) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = +autosize - } else if cursym.Text.Mark&LEAF == 0 { - if cursym.Text.From3.Offset&obj.NOSPLIT != 0 { - if ctxt.Debugvlog != 0 { - ctxt.Logf("save suppressed in: %s\n", cursym.Name) - } - - cursym.Text.Mark |= LEAF - } - } - - if cursym.Text.Mark&LEAF != 0 { - cursym.Set(obj.AttrLeaf, true) - break - } - - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOVV g_panic(g), R1 - // BEQ R1, end - // MOVV panic_argp(R1), R2 - // ADDV $(autosize+8), R29, R3 - // BNE R2, R3, end - // ADDV $8, R29, R2 - // MOVV R2, panic_argp(R1) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not an mips NOP: it encodes to 0 instruction bytes. - - q = obj.Appendp(ctxt, q) - - q.As = AMOVV - q.From.Type = obj.TYPE_MEM - q.From.Reg = REGG - q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R1 - - q = obj.Appendp(ctxt, q) - q.As = ABEQ - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R1 - q.To.Type = obj.TYPE_BRANCH - q.Mark |= BRANCH - p1 = q - - q = obj.Appendp(ctxt, q) - q.As = AMOVV - q.From.Type = obj.TYPE_MEM - q.From.Reg = REG_R1 - q.From.Offset = 0 // Panic.argp - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R2 - - q = obj.Appendp(ctxt, q) - q.As = AADDV - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(autosize) + 8 - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R3 - - q = obj.Appendp(ctxt, q) - q.As = ABNE - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R2 - q.Reg = REG_R3 - q.To.Type = obj.TYPE_BRANCH - q.Mark |= BRANCH - p2 = q - - q = obj.Appendp(ctxt, q) - q.As = AADDV - q.From.Type = obj.TYPE_CONST - q.From.Offset = 8 - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R2 - - q = obj.Appendp(ctxt, q) - q.As = AMOVV - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R2 - q.To.Type = obj.TYPE_MEM - q.To.Reg = REG_R1 - q.To.Offset = 0 // Panic.argp - - q = obj.Appendp(ctxt, q) - - q.As = obj.ANOP - p1.Pcond = q - p2.Pcond = q - } - - case ARET: - if p.From.Type == obj.TYPE_CONST { - ctxt.Diag("using BECOME (%v) is not supported!", p) - break - } - - retSym := p.To.Sym - p.To.Name = obj.NAME_NONE // clear fields as we may modify p to other instruction - p.To.Sym = nil - - if cursym.Text.Mark&LEAF != 0 { - if autosize == 0 { - p.As = AJMP - p.From = obj.Addr{} - if retSym != nil { // retjmp - p.To.Type = obj.TYPE_BRANCH - p.To.Name = obj.NAME_EXTERN - p.To.Sym = retSym - } else { - p.To.Type = obj.TYPE_MEM - p.To.Reg = REGLINK - p.To.Offset = 0 - } - p.Mark |= BRANCH - break - } - - p.As = AADDV - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autosize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REGSP - p.Spadj = -autosize - - q = ctxt.NewProg() - q.As = AJMP - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_MEM - q.To.Offset = 0 - q.To.Reg = REGLINK - q.Mark |= BRANCH - q.Spadj = +autosize - - q.Link = p.Link - p.Link = q - break - } - - p.As = AMOVV - p.From.Type = obj.TYPE_MEM - p.From.Offset = 0 - p.From.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - if retSym != nil { // retjmp from non-leaf, need to restore LINK register - p.To.Reg = REGLINK - } - - if autosize != 0 { - q = ctxt.NewProg() - q.As = AADDV - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(autosize) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = -autosize - - q.Link = p.Link - p.Link = q - } - - q1 = ctxt.NewProg() - q1.As = AJMP - q1.Lineno = p.Lineno - if retSym != nil { // retjmp - q1.To.Type = obj.TYPE_BRANCH - q1.To.Name = obj.NAME_EXTERN - q1.To.Sym = retSym - } else { - q1.To.Type = obj.TYPE_MEM - q1.To.Offset = 0 - q1.To.Reg = REG_R4 - } - q1.Mark |= BRANCH - q1.Spadj = +autosize - - q1.Link = q.Link - q.Link = q1 - - case AADDV, - AADDVU: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST { - p.Spadj = int32(-p.From.Offset) - } - } - } - - if nosched { - // if we don't do instruction scheduling, simply add - // NOP after each branch instruction. - for p = cursym.Text; p != nil; p = p.Link { - if p.Mark&BRANCH != 0 { - addnop(ctxt, p) - } - } - return - } - - // instruction scheduling - q = nil // p - 1 - q1 = cursym.Text // top of block - o := 0 // count of instructions - for p = cursym.Text; p != nil; p = p1 { - p1 = p.Link - o++ - if p.Mark&NOSCHED != 0 { - if q1 != p { - sched(ctxt, q1, q) - } - for ; p != nil; p = p.Link { - if p.Mark&NOSCHED == 0 { - break - } - q = p - } - p1 = p - q1 = p - o = 0 - continue - } - if p.Mark&(LABEL|SYNC) != 0 { - if q1 != p { - sched(ctxt, q1, q) - } - q1 = p - o = 1 - } - if p.Mark&(BRANCH|SYNC) != 0 { - sched(ctxt, q1, p) - q1 = p1 - o = 0 - } - if o >= NSCHED { - sched(ctxt, q1, p) - q1 = p1 - o = 0 - } - q = p - } -} - -func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { - // MOVV g_stackguard(g), R1 - p = obj.Appendp(ctxt, p) - - p.As = AMOVV - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - - var q *obj.Prog - if framesize <= obj.StackSmall { - // small stack: SP < stackguard - // AGTU SP, stackguard, R1 - p = obj.Appendp(ctxt, p) - - p.As = ASGTU - p.From.Type = obj.TYPE_REG - p.From.Reg = REGSP - p.Reg = REG_R1 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - } else if framesize <= obj.StackBig { - // large stack: SP-framesize < stackguard-StackSmall - // ADDV $-framesize, SP, R2 - // SGTU R2, stackguard, R1 - p = obj.Appendp(ctxt, p) - - p.As = AADDV - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(-framesize) - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = ASGTU - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R2 - p.Reg = REG_R1 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - } else { - // Such a large stack we need to protect against wraparound. - // If SP is close to zero: - // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // - // Preemption sets stackguard to StackPreempt, a very large value. - // That breaks the math above, so we have to check for that explicitly. - // // stackguard is R1 - // MOVV $StackPreempt, R2 - // BEQ R1, R2, label-of-call-to-morestack - // ADDV $StackGuard, SP, R2 - // SUBVU R1, R2 - // MOVV $(framesize+(StackGuard-StackSmall)), R1 - // SGTU R2, R1, R1 - p = obj.Appendp(ctxt, p) - - p.As = AMOVV - p.From.Type = obj.TYPE_CONST - p.From.Offset = obj.StackPreempt - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - q = p - p.As = ABEQ - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.Reg = REG_R2 - p.To.Type = obj.TYPE_BRANCH - p.Mark |= BRANCH - - p = obj.Appendp(ctxt, p) - p.As = AADDV - p.From.Type = obj.TYPE_CONST - p.From.Offset = obj.StackGuard - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = ASUBVU - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - - p = obj.Appendp(ctxt, p) - p.As = AMOVV - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - - p = obj.Appendp(ctxt, p) - p.As = ASGTU - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R2 - p.Reg = REG_R1 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R1 - } - - // q1: BNE R1, done - p = obj.Appendp(ctxt, p) - q1 := p - - p.As = ABNE - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 - p.To.Type = obj.TYPE_BRANCH - p.Mark |= BRANCH - - // MOVV LINK, R3 - p = obj.Appendp(ctxt, p) - - p.As = AMOVV - p.From.Type = obj.TYPE_REG - p.From.Reg = REGLINK - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - if q != nil { - q.Pcond = p - p.Mark |= LABEL - } - - // JAL runtime.morestack(SB) - p = obj.Appendp(ctxt, p) - - p.As = AJAL - p.To.Type = obj.TYPE_BRANCH - if ctxt.Cursym.CFunc() { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) - } else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0) - } else { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack", 0) - } - p.Mark |= BRANCH - - // JMP start - p = obj.Appendp(ctxt, p) - - p.As = AJMP - p.To.Type = obj.TYPE_BRANCH - p.Pcond = ctxt.Cursym.Text.Link - p.Mark |= BRANCH - - // placeholder for q1's jump target - p = obj.Appendp(ctxt, p) - - p.As = obj.ANOP // zero-width place holder - q1.Pcond = p - - return p -} - -func addnop(ctxt *obj.Link, p *obj.Prog) { - q := ctxt.NewProg() - // we want to use the canonical NOP (SLL $0,R0,R0) here, - // however, as the assembler will always replace $0 - // as R0, we have to resort to manually encode the SLL - // instruction as WORD $0. - q.As = AWORD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Name = obj.NAME_NONE - q.From.Offset = 0 - - q.Link = p.Link - p.Link = q -} - -const ( - E_HILO = 1 << 0 - E_FCR = 1 << 1 - E_MCR = 1 << 2 - E_MEM = 1 << 3 - E_MEMSP = 1 << 4 /* uses offset and size */ - E_MEMSB = 1 << 5 /* uses offset and size */ - ANYMEM = E_MEM | E_MEMSP | E_MEMSB - //DELAY = LOAD|BRANCH|FCMP - DELAY = BRANCH /* only schedule branch */ -) - -type Dep struct { - ireg uint32 - freg uint32 - cc uint32 -} - -type Sch struct { - p obj.Prog - set Dep - used Dep - soffset int32 - size uint8 - nop uint8 - comp bool -} - -func sched(ctxt *obj.Link, p0, pe *obj.Prog) { - var sch [NSCHED]Sch - - /* - * build side structure - */ - s := sch[:] - for p := p0; ; p = p.Link { - s[0].p = *p - markregused(ctxt, &s[0]) - if p == pe { - break - } - s = s[1:] - } - se := s - - for i := cap(sch) - cap(se); i >= 0; i-- { - s = sch[i:] - if s[0].p.Mark&DELAY == 0 { - continue - } - if -cap(s) < -cap(se) { - if !conflict(&s[0], &s[1]) { - continue - } - } - - var t []Sch - var j int - for j = cap(sch) - cap(s) - 1; j >= 0; j-- { - t = sch[j:] - if t[0].comp { - if s[0].p.Mark&BRANCH != 0 { - goto no2 - } - } - if t[0].p.Mark&DELAY != 0 { - if -cap(s) >= -cap(se) || conflict(&t[0], &s[1]) { - goto no2 - } - } - for u := t[1:]; -cap(u) <= -cap(s); u = u[1:] { - if depend(ctxt, &u[0], &t[0]) { - goto no2 - } - } - goto out2 - no2: - } - - if s[0].p.Mark&BRANCH != 0 { - s[0].nop = 1 - } - continue - - out2: - // t[0] is the instruction being moved to fill the delay - stmp := t[0] - copy(t[:i-j], t[1:i-j+1]) - s[0] = stmp - - if t[i-j-1].p.Mark&BRANCH != 0 { - // t[i-j] is being put into a branch delay slot - // combine its Spadj with the branch instruction - t[i-j-1].p.Spadj += t[i-j].p.Spadj - t[i-j].p.Spadj = 0 - } - - i-- - } - - /* - * put it all back - */ - var p *obj.Prog - var q *obj.Prog - for s, p = sch[:], p0; -cap(s) <= -cap(se); s, p = s[1:], q { - q = p.Link - if q != s[0].p.Link { - *p = s[0].p - p.Link = q - } - for s[0].nop != 0 { - s[0].nop-- - addnop(ctxt, p) - } - } -} - -func markregused(ctxt *obj.Link, s *Sch) { - p := &s.p - s.comp = compound(ctxt, p) - s.nop = 0 - if s.comp { - s.set.ireg |= 1 << (REGTMP - REG_R0) - s.used.ireg |= 1 << (REGTMP - REG_R0) - } - - ar := 0 /* dest is really reference */ - ad := 0 /* source/dest is really address */ - ld := 0 /* opcode is load instruction */ - sz := 20 /* size of load/store for overlap computation */ - - /* - * flags based on opcode - */ - switch p.As { - case obj.ATEXT: - ctxt.Autosize = int32(p.To.Offset + 8) - ad = 1 - - case AJAL: - c := p.Reg - if c == 0 { - c = REGLINK - } - s.set.ireg |= 1 << uint(c-REG_R0) - ar = 1 - ad = 1 - - case ABGEZAL, - ABLTZAL: - s.set.ireg |= 1 << (REGLINK - REG_R0) - fallthrough - case ABEQ, - ABGEZ, - ABGTZ, - ABLEZ, - ABLTZ, - ABNE: - ar = 1 - ad = 1 - - case ABFPT, - ABFPF: - ad = 1 - s.used.cc |= E_FCR - - case ACMPEQD, - ACMPEQF, - ACMPGED, - ACMPGEF, - ACMPGTD, - ACMPGTF: - ar = 1 - s.set.cc |= E_FCR - p.Mark |= FCMP - - case AJMP: - ar = 1 - ad = 1 - - case AMOVB, - AMOVBU: - sz = 1 - ld = 1 - - case AMOVH, - AMOVHU: - sz = 2 - ld = 1 - - case AMOVF, - AMOVW, - AMOVWL, - AMOVWR: - sz = 4 - ld = 1 - - case AMOVD, - AMOVV, - AMOVVL, - AMOVVR: - sz = 8 - ld = 1 - - case ADIV, - ADIVU, - AMUL, - AMULU, - AREM, - AREMU, - ADIVV, - ADIVVU, - AMULV, - AMULVU, - AREMV, - AREMVU: - s.set.cc = E_HILO - fallthrough - case AADD, - AADDU, - AADDV, - AADDVU, - AAND, - ANOR, - AOR, - ASGT, - ASGTU, - ASLL, - ASRA, - ASRL, - ASLLV, - ASRAV, - ASRLV, - ASUB, - ASUBU, - ASUBV, - ASUBVU, - AXOR, - - AADDD, - AADDF, - AADDW, - ASUBD, - ASUBF, - ASUBW, - AMULF, - AMULD, - AMULW, - ADIVF, - ADIVD, - ADIVW: - if p.Reg == 0 { - if p.To.Type == obj.TYPE_REG { - p.Reg = p.To.Reg - } - //if(p->reg == NREG) - // print("botch %P\n", p); - } - } - - /* - * flags based on 'to' field - */ - c := int(p.To.Class) - if c == 0 { - c = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(c) - } - c-- - switch c { - default: - fmt.Printf("unknown class %d %v\n", c, p) - - case C_ZCON, - C_SCON, - C_ADD0CON, - C_AND0CON, - C_ADDCON, - C_ANDCON, - C_UCON, - C_LCON, - C_NONE, - C_SBRA, - C_LBRA, - C_ADDR, - C_TEXTSIZE: - break - - case C_HI, - C_LO: - s.set.cc |= E_HILO - - case C_FCREG: - s.set.cc |= E_FCR - - case C_MREG: - s.set.cc |= E_MCR - - case C_ZOREG, - C_SOREG, - C_LOREG: - c = int(p.To.Reg) - s.used.ireg |= 1 << uint(c-REG_R0) - if ad != 0 { - break - } - s.size = uint8(sz) - s.soffset = regoff(ctxt, &p.To) - - m := uint32(ANYMEM) - if c == REGSB { - m = E_MEMSB - } - if c == REGSP { - m = E_MEMSP - } - - if ar != 0 { - s.used.cc |= m - } else { - s.set.cc |= m - } - - case C_SACON, - C_LACON: - s.used.ireg |= 1 << (REGSP - REG_R0) - - case C_SECON, - C_LECON: - s.used.ireg |= 1 << (REGSB - REG_R0) - - case C_REG: - if ar != 0 { - s.used.ireg |= 1 << uint(p.To.Reg-REG_R0) - } else { - s.set.ireg |= 1 << uint(p.To.Reg-REG_R0) - } - - case C_FREG: - if ar != 0 { - s.used.freg |= 1 << uint(p.To.Reg-REG_F0) - } else { - s.set.freg |= 1 << uint(p.To.Reg-REG_F0) - } - if ld != 0 && p.From.Type == obj.TYPE_REG { - p.Mark |= LOAD - } - - case C_SAUTO, - C_LAUTO: - s.used.ireg |= 1 << (REGSP - REG_R0) - if ad != 0 { - break - } - s.size = uint8(sz) - s.soffset = regoff(ctxt, &p.To) - - if ar != 0 { - s.used.cc |= E_MEMSP - } else { - s.set.cc |= E_MEMSP - } - - case C_SEXT, - C_LEXT: - s.used.ireg |= 1 << (REGSB - REG_R0) - if ad != 0 { - break - } - s.size = uint8(sz) - s.soffset = regoff(ctxt, &p.To) - - if ar != 0 { - s.used.cc |= E_MEMSB - } else { - s.set.cc |= E_MEMSB - } - } - - /* - * flags based on 'from' field - */ - c = int(p.From.Class) - if c == 0 { - c = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(c) - } - c-- - switch c { - default: - fmt.Printf("unknown class %d %v\n", c, p) - - case C_ZCON, - C_SCON, - C_ADD0CON, - C_AND0CON, - C_ADDCON, - C_ANDCON, - C_UCON, - C_LCON, - C_NONE, - C_SBRA, - C_LBRA, - C_ADDR, - C_TEXTSIZE: - break - - case C_HI, - C_LO: - s.used.cc |= E_HILO - - case C_FCREG: - s.used.cc |= E_FCR - - case C_MREG: - s.used.cc |= E_MCR - - case C_ZOREG, - C_SOREG, - C_LOREG: - c = int(p.From.Reg) - s.used.ireg |= 1 << uint(c-REG_R0) - if ld != 0 { - p.Mark |= LOAD - } - s.size = uint8(sz) - s.soffset = regoff(ctxt, &p.From) - - m := uint32(ANYMEM) - if c == REGSB { - m = E_MEMSB - } - if c == REGSP { - m = E_MEMSP - } - - s.used.cc |= m - - case C_SACON, - C_LACON: - c = int(p.From.Reg) - if c == 0 { - c = REGSP - } - s.used.ireg |= 1 << uint(c-REG_R0) - - case C_SECON, - C_LECON: - s.used.ireg |= 1 << (REGSB - REG_R0) - - case C_REG: - s.used.ireg |= 1 << uint(p.From.Reg-REG_R0) - - case C_FREG: - s.used.freg |= 1 << uint(p.From.Reg-REG_F0) - if ld != 0 && p.To.Type == obj.TYPE_REG { - p.Mark |= LOAD - } - - case C_SAUTO, - C_LAUTO: - s.used.ireg |= 1 << (REGSP - REG_R0) - if ld != 0 { - p.Mark |= LOAD - } - if ad != 0 { - break - } - s.size = uint8(sz) - s.soffset = regoff(ctxt, &p.From) - - s.used.cc |= E_MEMSP - - case C_SEXT: - case C_LEXT: - s.used.ireg |= 1 << (REGSB - REG_R0) - if ld != 0 { - p.Mark |= LOAD - } - if ad != 0 { - break - } - s.size = uint8(sz) - s.soffset = regoff(ctxt, &p.From) - - s.used.cc |= E_MEMSB - } - - c = int(p.Reg) - if c != 0 { - if REG_F0 <= c && c <= REG_F31 { - s.used.freg |= 1 << uint(c-REG_F0) - } else { - s.used.ireg |= 1 << uint(c-REG_R0) - } - } - s.set.ireg &^= (1 << (REGZERO - REG_R0)) /* R0 can't be set */ -} - -/* - * test to see if two instructions can be - * interchanged without changing semantics - */ -func depend(ctxt *obj.Link, sa, sb *Sch) bool { - if sa.set.ireg&(sb.set.ireg|sb.used.ireg) != 0 { - return true - } - if sb.set.ireg&sa.used.ireg != 0 { - return true - } - - if sa.set.freg&(sb.set.freg|sb.used.freg) != 0 { - return true - } - if sb.set.freg&sa.used.freg != 0 { - return true - } - - /* - * special case. - * loads from same address cannot pass. - * this is for hardware fifo's and the like - */ - if sa.used.cc&sb.used.cc&E_MEM != 0 { - if sa.p.Reg == sb.p.Reg { - if regoff(ctxt, &sa.p.From) == regoff(ctxt, &sb.p.From) { - return true - } - } - } - - x := (sa.set.cc & (sb.set.cc | sb.used.cc)) | (sb.set.cc & sa.used.cc) - if x != 0 { - /* - * allow SB and SP to pass each other. - * allow SB to pass SB iff doffsets are ok - * anything else conflicts - */ - if x != E_MEMSP && x != E_MEMSB { - return true - } - x = sa.set.cc | sb.set.cc | sa.used.cc | sb.used.cc - if x&E_MEM != 0 { - return true - } - if offoverlap(sa, sb) { - return true - } - } - - return false -} - -func offoverlap(sa, sb *Sch) bool { - if sa.soffset < sb.soffset { - if sa.soffset+int32(sa.size) > sb.soffset { - return true - } - return false - } - if sb.soffset+int32(sb.size) > sa.soffset { - return true - } - return false -} - -/* - * test 2 adjacent instructions - * and find out if inserted instructions - * are desired to prevent stalls. - */ -func conflict(sa, sb *Sch) bool { - if sa.set.ireg&sb.used.ireg != 0 { - return true - } - if sa.set.freg&sb.used.freg != 0 { - return true - } - if sa.set.cc&sb.used.cc != 0 { - return true - } - return false -} - -func compound(ctxt *obj.Link, p *obj.Prog) bool { - o := oplook(ctxt, p) - if o.size != 4 { - return true - } - if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSB { - return true - } - return false -} - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var r *obj.Prog - var i int - -loop: - if p == nil { - return - } - a := p.As - if a == AJMP { - q = p.Pcond - if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) { - p.Mark |= FOLL - (*last).Link = p - *last = p - p = p.Link - xfol(ctxt, p, last) - p = q - if p != nil && p.Mark&FOLL == 0 { - goto loop - } - return - } - - if q != nil { - p.Mark |= FOLL - p = q - if p.Mark&FOLL == 0 { - goto loop - } - } - } - - if p.Mark&FOLL != 0 { - i = 0 - q = p - for ; i < 4; i, q = i+1, q.Link { - if q == *last || (q.Mark&NOSCHED != 0) { - break - } - a = q.As - if a == obj.ANOP { - i-- - continue - } - - if a == AJMP || a == ARET || a == ARFE { - goto copy - } - if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { - continue - } - if a != ABEQ && a != ABNE { - continue - } - - copy: - for { - r = ctxt.NewProg() - *r = *p - if r.Mark&FOLL == 0 { - fmt.Printf("can't happen 1\n") - } - r.Mark |= FOLL - if p != q { - p = p.Link - (*last).Link = r - *last = r - continue - } - - (*last).Link = r - *last = r - if a == AJMP || a == ARET || a == ARFE { - return - } - r.As = ABNE - if a == ABNE { - r.As = ABEQ - } - r.Pcond = p.Link - r.Link = p.Pcond - if r.Link.Mark&FOLL == 0 { - xfol(ctxt, r.Link, last) - } - if r.Pcond.Mark&FOLL == 0 { - fmt.Printf("can't happen 2\n") - } - return - } - } - - a = AJMP - q = ctxt.NewProg() - q.As = a - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - p.Mark |= FOLL - (*last).Link = p - *last = p - if a == AJMP || a == ARET || a == ARFE { - if p.Mark&NOSCHED != 0 { - p = p.Link - goto loop - } - - return - } - - if p.Pcond != nil { - if a != AJAL && p.Link != nil { - xfol(ctxt, p.Link, last) - p = p.Pcond - if p == nil || (p.Mark&FOLL != 0) { - return - } - goto loop - } - } - - p = p.Link - goto loop -} - -var Linkmips64 = obj.LinkArch{ - Arch: sys.ArchMIPS64, - Preprocess: preprocess, - Assemble: span0, - Follow: follow, - Progedit: progedit, -} - -var Linkmips64le = obj.LinkArch{ - Arch: sys.ArchMIPS64LE, - Preprocess: preprocess, - Assemble: span0, - Follow: follow, - Progedit: progedit, -} diff --git a/vendor/github.com/google/gops/internal/obj/obj.go b/vendor/github.com/google/gops/internal/obj/obj.go deleted file mode 100644 index 566263d3..00000000 --- a/vendor/github.com/google/gops/internal/obj/obj.go +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2009 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 obj - -import ( - "fmt" - "path/filepath" - "sort" - "strings" -) - -// A LineHist records the history of the file input stack, which maps the virtual line number, -// an incrementing count of lines processed in any input file and typically named lineno, -// to a stack of file:line pairs showing the path of inclusions that led to that position. -// The first line directive (//line in Go, #line in assembly) is treated as pushing -// a new entry on the stack, so that errors can report both the actual and translated -// line number. -// -// In typical use, the virtual lineno begins at 1, and file line numbers also begin at 1, -// but the only requirements placed upon the numbers by this code are: -// - calls to Push, Update, and Pop must be monotonically increasing in lineno -// - except as specified by those methods, virtual and file line number increase -// together, so that given (only) calls Push(10, "x.go", 1) and Pop(15), -// virtual line 12 corresponds to x.go line 3. -type LineHist struct { - Top *LineStack // current top of stack - Ranges []LineRange // ranges for lookup - Dir string // directory to qualify relative paths - TrimPathPrefix string // remove leading TrimPath from recorded file names - PrintFilenameOnly bool // ignore path when pretty-printing a line; internal use only - GOROOT string // current GOROOT -} - -// A LineStack is an entry in the recorded line history. -// Although the history at any given line number is a stack, -// the record for all line processed forms a tree, with common -// stack prefixes acting as parents. -type LineStack struct { - Parent *LineStack // parent in inclusion stack - Lineno int // virtual line number where this entry takes effect - File string // file name used to open source file, for error messages - AbsFile string // absolute file name, for pcln tables - FileLine int // line number in file at Lineno - Directive bool - Sym *LSym // for linkgetline - TODO(rsc): remove -} - -func (stk *LineStack) fileLineAt(lineno int) int { - return stk.FileLine + lineno - stk.Lineno -} - -// The span of valid linenos in the recorded line history can be broken -// into a set of ranges, each with a particular stack. -// A LineRange records one such range. -type LineRange struct { - Start int // starting lineno - Stack *LineStack // top of stack for this range -} - -// startRange starts a new range with the given top of stack. -func (h *LineHist) startRange(lineno int, top *LineStack) { - h.Top = top - h.Ranges = append(h.Ranges, LineRange{top.Lineno, top}) -} - -// setFile sets stk.File = file and also derives stk.AbsFile. -func (h *LineHist) setFile(stk *LineStack, file string) { - // Note: The exclusion of stk.Directive may be wrong but matches what we've done before. - // The check for < avoids putting a path prefix on "". - abs := file - if h.Dir != "" && !filepath.IsAbs(file) && !strings.HasPrefix(file, "<") && !stk.Directive { - abs = filepath.Join(h.Dir, file) - } - - // Remove leading TrimPathPrefix, or else rewrite $GOROOT to literal $GOROOT. - if h.TrimPathPrefix != "" && hasPathPrefix(abs, h.TrimPathPrefix) { - if abs == h.TrimPathPrefix { - abs = "" - } else { - abs = abs[len(h.TrimPathPrefix)+1:] - } - } else if hasPathPrefix(abs, h.GOROOT) { - abs = "$GOROOT" + abs[len(h.GOROOT):] - } - if abs == "" { - abs = "??" - } - abs = filepath.Clean(abs) - stk.AbsFile = abs - - if file == "" { - file = "??" - } - stk.File = file -} - -// Does s have t as a path prefix? -// That is, does s == t or does s begin with t followed by a slash? -// For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true. -// Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true. -// We do not allow full Unicode case folding, for fear of causing more confusion -// or harm than good. (For an example of the kinds of things that can go wrong, -// see http://article.gmane.org/gmane.linux.kernel/1853266.) -func hasPathPrefix(s string, t string) bool { - if len(t) > len(s) { - return false - } - var i int - for i = 0; i < len(t); i++ { - cs := int(s[i]) - ct := int(t[i]) - if 'A' <= cs && cs <= 'Z' { - cs += 'a' - 'A' - } - if 'A' <= ct && ct <= 'Z' { - ct += 'a' - 'A' - } - if cs == '\\' { - cs = '/' - } - if ct == '\\' { - ct = '/' - } - if cs != ct { - return false - } - } - return i >= len(s) || s[i] == '/' || s[i] == '\\' -} - -// Push records that at that lineno a new file with the given name was pushed onto the input stack. -func (h *LineHist) Push(lineno int, file string) { - stk := &LineStack{ - Parent: h.Top, - Lineno: lineno, - FileLine: 1, - } - h.setFile(stk, file) - h.startRange(lineno, stk) -} - -// Pop records that at lineno the current file was popped from the input stack. -func (h *LineHist) Pop(lineno int) { - top := h.Top - if top == nil { - return - } - if top.Directive && top.Parent != nil { // pop #line level too - top = top.Parent - } - next := top.Parent - if next == nil { - h.Top = nil - h.Ranges = append(h.Ranges, LineRange{lineno, nil}) - return - } - - // Popping included file. Update parent offset to account for - // the virtual line number range taken by the included file. - // Cannot modify the LineStack directly, or else lookups - // for the earlier line numbers will get the wrong answers, - // so make a new one. - stk := new(LineStack) - *stk = *next - stk.Lineno = lineno - stk.FileLine = next.fileLineAt(top.Lineno) - h.startRange(lineno, stk) -} - -// Update records that at lineno the file name and line number were changed using -// a line directive (//line in Go, #line in assembly). -func (h *LineHist) Update(lineno int, file string, line int) { - top := h.Top - if top == nil { - return // shouldn't happen - } - var stk *LineStack - if top.Directive { - // Update existing entry, except make copy to avoid changing earlier history. - stk = new(LineStack) - *stk = *top - } else { - // Push new entry. - stk = &LineStack{ - Parent: top, - Directive: true, - } - } - stk.Lineno = lineno - if stk.File != file { - h.setFile(stk, file) // only retain string if needed - } - stk.FileLine = line - h.startRange(lineno, stk) -} - -// AddImport adds a package to the list of imported packages. -func (ctxt *Link) AddImport(pkg string) { - ctxt.Imports = append(ctxt.Imports, pkg) -} - -// At returns the input stack in effect at lineno. -func (h *LineHist) At(lineno int) *LineStack { - i := sort.Search(len(h.Ranges), func(i int) bool { - return h.Ranges[i].Start > lineno - }) - // Found first entry beyond lineno. - if i == 0 { - return nil - } - return h.Ranges[i-1].Stack -} - -// LineString returns a string giving the file and line number -// corresponding to lineno, for use in error messages. -func (h *LineHist) LineString(lineno int) string { - stk := h.At(lineno) - if stk == nil { - return "" - } - - filename := stk.File - if h.PrintFilenameOnly { - filename = filepath.Base(filename) - } - text := fmt.Sprintf("%s:%d", filename, stk.fileLineAt(lineno)) - if stk.Directive && stk.Parent != nil { - stk = stk.Parent - filename = stk.File - if h.PrintFilenameOnly { - filename = filepath.Base(filename) - } - text += fmt.Sprintf("[%s:%d]", filename, stk.fileLineAt(lineno)) - } - const showFullStack = false // was used by old C compilers - if showFullStack { - for stk.Parent != nil { - lineno = stk.Lineno - 1 - stk = stk.Parent - text += fmt.Sprintf(" %s:%d", filename, stk.fileLineAt(lineno)) - if stk.Directive && stk.Parent != nil { - stk = stk.Parent - text += fmt.Sprintf("[%s:%d]", filename, stk.fileLineAt(lineno)) - } - } - } - return text -} - -// FileLine returns the file name and line number -// at the top of the stack for the given lineno. -func (h *LineHist) FileLine(lineno int) (file string, line int) { - stk := h.At(lineno) - if stk == nil { - return "??", 0 - } - return stk.File, stk.fileLineAt(lineno) -} - -// AbsFileLine returns the absolute file name and line number -// at the top of the stack for the given lineno. -func (h *LineHist) AbsFileLine(lineno int) (file string, line int) { - stk := h.At(lineno) - if stk == nil { - return "??", 0 - } - return stk.AbsFile, stk.fileLineAt(lineno) -} - -// This is a simplified copy of linklinefmt above. -// It doesn't allow printing the full stack, and it returns the file name and line number separately. -// TODO: Unify with linklinefmt somehow. -func linkgetline(ctxt *Link, lineno int32) (f *LSym, l int32) { - stk := ctxt.LineHist.At(int(lineno)) - if stk == nil || stk.AbsFile == "" { - return Linklookup(ctxt, "??", HistVersion), 0 - } - if stk.Sym == nil { - stk.Sym = Linklookup(ctxt, stk.AbsFile, HistVersion) - } - return stk.Sym, int32(stk.fileLineAt(int(lineno))) -} - -func Linkprfile(ctxt *Link, line int) { - fmt.Printf("%s ", ctxt.LineHist.LineString(line)) -} - -func fieldtrack(ctxt *Link, cursym *LSym) { - p := cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - ctxt.Cursym = cursym - - for ; p != nil; p = p.Link { - if p.As == AUSEFIELD { - r := Addrel(ctxt.Cursym) - r.Off = 0 - r.Siz = 0 - r.Sym = p.From.Sym - r.Type = R_USEFIELD - } - } -} diff --git a/vendor/github.com/google/gops/internal/obj/objfile.go b/vendor/github.com/google/gops/internal/obj/objfile.go deleted file mode 100644 index 8a897f09..00000000 --- a/vendor/github.com/google/gops/internal/obj/objfile.go +++ /dev/null @@ -1,606 +0,0 @@ -// Copyright 2013 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. - -// Writing of Go object files. -// -// Originally, Go object files were Plan 9 object files, but no longer. -// Now they are more like standard object files, in that each symbol is defined -// by an associated memory image (bytes) and a list of relocations to apply -// during linking. We do not (yet?) use a standard file format, however. -// For now, the format is chosen to be as simple as possible to read and write. -// It may change for reasons of efficiency, or we may even switch to a -// standard file format if there are compelling benefits to doing so. -// See golang.org/s/go13linker for more background. -// -// The file format is: -// -// - magic header: "\x00\x00go17ld" -// - byte 1 - version number -// - sequence of strings giving dependencies (imported packages) -// - empty string (marks end of sequence) -// - sequence of symbol references used by the defined symbols -// - byte 0xff (marks end of sequence) -// - sequence of integer lengths: -// - total data length -// - total number of relocations -// - total number of pcdata -// - total number of automatics -// - total number of funcdata -// - total number of files -// - data, the content of the defined symbols -// - sequence of defined symbols -// - byte 0xff (marks end of sequence) -// - magic footer: "\xff\xffgo17ld" -// -// All integers are stored in a zigzag varint format. -// See golang.org/s/go12symtab for a definition. -// -// Data blocks and strings are both stored as an integer -// followed by that many bytes. -// -// A symbol reference is a string name followed by a version. -// -// A symbol points to other symbols using an index into the symbol -// reference sequence. Index 0 corresponds to a nil LSym* pointer. -// In the symbol layout described below "symref index" stands for this -// index. -// -// Each symbol is laid out as the following fields (taken from LSym*): -// -// - byte 0xfe (sanity check for synchronization) -// - type [int] -// - name & version [symref index] -// - flags [int] -// 1<<0 dupok -// 1<<1 local -// 1<<2 add to typelink table -// - size [int] -// - gotype [symref index] -// - p [data block] -// - nr [int] -// - r [nr relocations, sorted by off] -// -// If type == STEXT, there are a few more fields: -// -// - args [int] -// - locals [int] -// - nosplit [int] -// - flags [int] -// 1<<0 leaf -// 1<<1 C function -// 1<<2 function may call reflect.Type.Method -// - nlocal [int] -// - local [nlocal automatics] -// - pcln [pcln table] -// -// Each relocation has the encoding: -// -// - off [int] -// - siz [int] -// - type [int] -// - add [int] -// - sym [symref index] -// -// Each local has the encoding: -// -// - asym [symref index] -// - offset [int] -// - type [int] -// - gotype [symref index] -// -// The pcln table has the encoding: -// -// - pcsp [data block] -// - pcfile [data block] -// - pcline [data block] -// - npcdata [int] -// - pcdata [npcdata data blocks] -// - nfuncdata [int] -// - funcdata [nfuncdata symref index] -// - funcdatasym [nfuncdata ints] -// - nfile [int] -// - file [nfile symref index] -// -// The file layout and meaning of type integers are architecture-independent. -// -// TODO(rsc): The file format is good for a first pass but needs work. -// - There are SymID in the object file that should really just be strings. - -package obj - -import ( - "bufio" - "fmt" - "log" - "path/filepath" - "sort" - - "github.com/google/gops/internal/dwarf" - "github.com/google/gops/internal/sys" -) - -// The Go and C compilers, and the assembler, call writeobj to write -// out a Go object file. The linker does not call this; the linker -// does not write out object files. -func Writeobjdirect(ctxt *Link, b *bufio.Writer) { - Flushplist(ctxt) - WriteObjFile(ctxt, b) -} - -// objWriter writes Go object files. -type objWriter struct { - wr *bufio.Writer - ctxt *Link - // Temporary buffer for zigzag int writing. - varintbuf [10]uint8 - - // Provide the the index of a symbol reference by symbol name. - // One map for versioned symbols and one for unversioned symbols. - // Used for deduplicating the symbol reference list. - refIdx map[string]int - vrefIdx map[string]int - - // Number of objects written of each type. - nRefs int - nData int - nReloc int - nPcdata int - nAutom int - nFuncdata int - nFile int -} - -func (w *objWriter) addLengths(s *LSym) { - w.nData += len(s.P) - w.nReloc += len(s.R) - - if s.Type != STEXT { - return - } - - pc := s.Pcln - - data := 0 - data += len(pc.Pcsp.P) - data += len(pc.Pcfile.P) - data += len(pc.Pcline.P) - for i := 0; i < len(pc.Pcdata); i++ { - data += len(pc.Pcdata[i].P) - } - - w.nData += data - w.nPcdata += len(pc.Pcdata) - - autom := 0 - for a := s.Autom; a != nil; a = a.Link { - autom++ - } - w.nAutom += autom - w.nFuncdata += len(pc.Funcdataoff) - w.nFile += len(pc.File) -} - -func (w *objWriter) writeLengths() { - w.writeInt(int64(w.nData)) - w.writeInt(int64(w.nReloc)) - w.writeInt(int64(w.nPcdata)) - w.writeInt(int64(w.nAutom)) - w.writeInt(int64(w.nFuncdata)) - w.writeInt(int64(w.nFile)) -} - -func newObjWriter(ctxt *Link, b *bufio.Writer) *objWriter { - return &objWriter{ - ctxt: ctxt, - wr: b, - vrefIdx: make(map[string]int), - refIdx: make(map[string]int), - } -} - -func WriteObjFile(ctxt *Link, b *bufio.Writer) { - w := newObjWriter(ctxt, b) - - // Magic header - w.wr.WriteString("\x00\x00go17ld") - - // Version - w.wr.WriteByte(1) - - // Autolib - for _, pkg := range ctxt.Imports { - w.writeString(pkg) - } - w.writeString("") - - // Symbol references - for _, s := range ctxt.Text { - w.writeRefs(s) - w.addLengths(s) - } - for _, s := range ctxt.Data { - w.writeRefs(s) - w.addLengths(s) - } - // End symbol references - w.wr.WriteByte(0xff) - - // Lengths - w.writeLengths() - - // Data block - for _, s := range ctxt.Text { - w.wr.Write(s.P) - pc := s.Pcln - w.wr.Write(pc.Pcsp.P) - w.wr.Write(pc.Pcfile.P) - w.wr.Write(pc.Pcline.P) - for i := 0; i < len(pc.Pcdata); i++ { - w.wr.Write(pc.Pcdata[i].P) - } - } - for _, s := range ctxt.Data { - w.wr.Write(s.P) - } - - // Symbols - for _, s := range ctxt.Text { - w.writeSym(s) - } - for _, s := range ctxt.Data { - w.writeSym(s) - } - - // Magic footer - w.wr.WriteString("\xff\xffgo17ld") -} - -// Symbols are prefixed so their content doesn't get confused with the magic footer. -const symPrefix = 0xfe - -func (w *objWriter) writeRef(s *LSym, isPath bool) { - if s == nil || s.RefIdx != 0 { - return - } - var m map[string]int - switch s.Version { - case 0: - m = w.refIdx - case 1: - m = w.vrefIdx - default: - log.Fatalf("%s: invalid version number %d", s.Name, s.Version) - } - - idx := m[s.Name] - if idx != 0 { - s.RefIdx = idx - return - } - w.wr.WriteByte(symPrefix) - if isPath { - w.writeString(filepath.ToSlash(s.Name)) - } else { - w.writeString(s.Name) - } - w.writeInt(int64(s.Version)) - w.nRefs++ - s.RefIdx = w.nRefs - m[s.Name] = w.nRefs -} - -func (w *objWriter) writeRefs(s *LSym) { - w.writeRef(s, false) - w.writeRef(s.Gotype, false) - for i := range s.R { - w.writeRef(s.R[i].Sym, false) - } - - if s.Type == STEXT { - for a := s.Autom; a != nil; a = a.Link { - w.writeRef(a.Asym, false) - w.writeRef(a.Gotype, false) - } - pc := s.Pcln - for _, d := range pc.Funcdata { - w.writeRef(d, false) - } - for _, f := range pc.File { - w.writeRef(f, true) - } - } -} - -func (w *objWriter) writeSymDebug(s *LSym) { - ctxt := w.ctxt - fmt.Fprintf(ctxt.Bso, "%s ", s.Name) - if s.Version != 0 { - fmt.Fprintf(ctxt.Bso, "v=%d ", s.Version) - } - if s.Type != 0 { - fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type) - } - if s.DuplicateOK() { - fmt.Fprintf(ctxt.Bso, "dupok ") - } - if s.CFunc() { - fmt.Fprintf(ctxt.Bso, "cfunc ") - } - if s.NoSplit() { - fmt.Fprintf(ctxt.Bso, "nosplit ") - } - fmt.Fprintf(ctxt.Bso, "size=%d", s.Size) - if s.Type == STEXT { - fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals)) - if s.Leaf() { - fmt.Fprintf(ctxt.Bso, " leaf") - } - } - - fmt.Fprintf(ctxt.Bso, "\n") - for p := s.Text; p != nil; p = p.Link { - fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p) - } - var c int - var j int - for i := 0; i < len(s.P); { - fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i)) - for j = i; j < i+16 && j < len(s.P); j++ { - fmt.Fprintf(ctxt.Bso, " %02x", s.P[j]) - } - for ; j < i+16; j++ { - fmt.Fprintf(ctxt.Bso, " ") - } - fmt.Fprintf(ctxt.Bso, " ") - for j = i; j < i+16 && j < len(s.P); j++ { - c = int(s.P[j]) - if ' ' <= c && c <= 0x7e { - fmt.Fprintf(ctxt.Bso, "%c", c) - } else { - fmt.Fprintf(ctxt.Bso, ".") - } - } - - fmt.Fprintf(ctxt.Bso, "\n") - i += 16 - } - - sort.Sort(relocByOff(s.R)) // generate stable output - for _, r := range s.R { - name := "" - if r.Sym != nil { - name = r.Sym.Name - } else if r.Type == R_TLS_LE { - name = "TLS" - } - if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(r.Add)) - } else { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, r.Add) - } - } -} - -func (w *objWriter) writeSym(s *LSym) { - ctxt := w.ctxt - if ctxt.Debugasm != 0 { - w.writeSymDebug(s) - } - - w.wr.WriteByte(symPrefix) - w.writeInt(int64(s.Type)) - w.writeRefIndex(s) - flags := int64(0) - if s.DuplicateOK() { - flags |= 1 - } - if s.Local() { - flags |= 1 << 1 - } - if s.MakeTypelink() { - flags |= 1 << 2 - } - w.writeInt(flags) - w.writeInt(s.Size) - w.writeRefIndex(s.Gotype) - w.writeInt(int64(len(s.P))) - - w.writeInt(int64(len(s.R))) - var r *Reloc - for i := 0; i < len(s.R); i++ { - r = &s.R[i] - w.writeInt(int64(r.Off)) - w.writeInt(int64(r.Siz)) - w.writeInt(int64(r.Type)) - w.writeInt(r.Add) - w.writeRefIndex(r.Sym) - } - - if s.Type != STEXT { - return - } - - w.writeInt(int64(s.Args)) - w.writeInt(int64(s.Locals)) - if s.NoSplit() { - w.writeInt(1) - } else { - w.writeInt(0) - } - flags = int64(0) - if s.Leaf() { - flags |= 1 - } - if s.CFunc() { - flags |= 1 << 1 - } - if s.ReflectMethod() { - flags |= 1 << 2 - } - w.writeInt(flags) - n := 0 - for a := s.Autom; a != nil; a = a.Link { - n++ - } - w.writeInt(int64(n)) - for a := s.Autom; a != nil; a = a.Link { - w.writeRefIndex(a.Asym) - w.writeInt(int64(a.Aoffset)) - if a.Name == NAME_AUTO { - w.writeInt(A_AUTO) - } else if a.Name == NAME_PARAM { - w.writeInt(A_PARAM) - } else { - log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name) - } - w.writeRefIndex(a.Gotype) - } - - pc := s.Pcln - w.writeInt(int64(len(pc.Pcsp.P))) - w.writeInt(int64(len(pc.Pcfile.P))) - w.writeInt(int64(len(pc.Pcline.P))) - w.writeInt(int64(len(pc.Pcdata))) - for i := 0; i < len(pc.Pcdata); i++ { - w.writeInt(int64(len(pc.Pcdata[i].P))) - } - w.writeInt(int64(len(pc.Funcdataoff))) - for i := 0; i < len(pc.Funcdataoff); i++ { - w.writeRefIndex(pc.Funcdata[i]) - } - for i := 0; i < len(pc.Funcdataoff); i++ { - w.writeInt(pc.Funcdataoff[i]) - } - w.writeInt(int64(len(pc.File))) - for _, f := range pc.File { - w.writeRefIndex(f) - } -} - -func (w *objWriter) writeInt(sval int64) { - var v uint64 - uv := (uint64(sval) << 1) ^ uint64(sval>>63) - p := w.varintbuf[:] - for v = uv; v >= 0x80; v >>= 7 { - p[0] = uint8(v | 0x80) - p = p[1:] - } - p[0] = uint8(v) - p = p[1:] - w.wr.Write(w.varintbuf[:len(w.varintbuf)-len(p)]) -} - -func (w *objWriter) writeString(s string) { - w.writeInt(int64(len(s))) - w.wr.WriteString(s) -} - -func (w *objWriter) writeRefIndex(s *LSym) { - if s == nil { - w.writeInt(0) - return - } - if s.RefIdx == 0 { - log.Fatalln("writing an unreferenced symbol", s.Name) - } - w.writeInt(int64(s.RefIdx)) -} - -// relocByOff sorts relocations by their offsets. -type relocByOff []Reloc - -func (x relocByOff) Len() int { return len(x) } -func (x relocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off } -func (x relocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -// implement dwarf.Context -type dwCtxt struct{ *Link } - -func (c dwCtxt) PtrSize() int { - return c.Arch.PtrSize -} -func (c dwCtxt) AddInt(s dwarf.Sym, size int, i int64) { - ls := s.(*LSym) - ls.WriteInt(c.Link, ls.Size, size, i) -} -func (c dwCtxt) AddBytes(s dwarf.Sym, b []byte) { - ls := s.(*LSym) - ls.WriteBytes(c.Link, ls.Size, b) -} -func (c dwCtxt) AddString(s dwarf.Sym, v string) { - ls := s.(*LSym) - ls.WriteString(c.Link, ls.Size, len(v), v) - ls.WriteInt(c.Link, ls.Size, 1, 0) -} -func (c dwCtxt) SymValue(s dwarf.Sym) int64 { - return 0 -} -func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { - rsym := data.(*LSym) - ls := s.(*LSym) - size := c.PtrSize() - ls.WriteAddr(c.Link, ls.Size, size, rsym, value) -} -func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { - ls := s.(*LSym) - rsym := t.(*LSym) - ls.WriteAddr(c.Link, ls.Size, size, rsym, ofs) - r := &ls.R[len(ls.R)-1] - r.Type = R_DWARFREF -} - -func gendwarf(ctxt *Link, text []*LSym) []*LSym { - dctxt := dwCtxt{ctxt} - var dw []*LSym - - for _, s := range text { - dsym := Linklookup(ctxt, dwarf.InfoPrefix+s.Name, int(s.Version)) - if dsym.Size != 0 { - continue - } - dw = append(dw, dsym) - dsym.Type = SDWARFINFO - dsym.Set(AttrDuplicateOK, s.DuplicateOK()) - var vars dwarf.Var - var abbrev int - var offs int32 - for a := s.Autom; a != nil; a = a.Link { - switch a.Name { - case NAME_AUTO: - abbrev = dwarf.DW_ABRV_AUTO - offs = a.Aoffset - if ctxt.FixedFrameSize() == 0 { - offs -= int32(ctxt.Arch.PtrSize) - } - if Framepointer_enabled(GOOS, GOARCH) { - offs -= int32(ctxt.Arch.PtrSize) - } - - case NAME_PARAM: - abbrev = dwarf.DW_ABRV_PARAM - offs = a.Aoffset + int32(ctxt.FixedFrameSize()) - - default: - continue - } - typename := dwarf.InfoPrefix + a.Gotype.Name[len("type."):] - dwvar := &dwarf.Var{ - Name: a.Asym.Name, - Abbrev: abbrev, - Offset: int32(offs), - Type: Linklookup(ctxt, typename, 0), - } - dws := &vars.Link - for ; *dws != nil; dws = &(*dws).Link { - if offs <= (*dws).Offset { - break - } - } - dwvar.Link = *dws - *dws = dwvar - } - dwarf.PutFunc(dctxt, dsym, s.Name, s.Version == 0, s, s.Size, vars.Link) - } - return dw -} diff --git a/vendor/github.com/google/gops/internal/obj/pass.go b/vendor/github.com/google/gops/internal/obj/pass.go deleted file mode 100644 index 1d2f74b9..00000000 --- a/vendor/github.com/google/gops/internal/obj/pass.go +++ /dev/null @@ -1,217 +0,0 @@ -// Inferno utils/6l/pass.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/pass.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package obj - -// Code and data passes. - -func Brchain(ctxt *Link, p *Prog) *Prog { - for i := 0; i < 20; i++ { - if p == nil || p.As != AJMP || p.Pcond == nil { - return p - } - p = p.Pcond - } - - return nil -} - -func brloop(ctxt *Link, p *Prog) *Prog { - var q *Prog - - c := 0 - for q = p; q != nil; q = q.Pcond { - if q.As != AJMP || q.Pcond == nil { - break - } - c++ - if c >= 5000 { - return nil - } - } - - return q -} - -func checkaddr(ctxt *Link, p *Prog, a *Addr) { - // Check expected encoding, especially TYPE_CONST vs TYPE_ADDR. - switch a.Type { - case TYPE_NONE: - return - - case TYPE_BRANCH: - if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 { - break - } - return - - case TYPE_TEXTSIZE: - if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 { - break - } - return - - //if(a->u.bits != 0) - // break; - case TYPE_MEM: - return - - // TODO(rsc): After fixing SHRQ, check a->index != 0 too. - case TYPE_CONST: - if a.Name != 0 || a.Sym != nil || a.Reg != 0 { - ctxt.Diag("argument is TYPE_CONST, should be TYPE_ADDR, in %v", p) - return - } - - if a.Reg != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil { - break - } - return - - case TYPE_FCONST, TYPE_SCONST: - if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Offset != 0 || a.Sym != nil { - break - } - return - - // TODO(rsc): After fixing PINSRQ, check a->offset != 0 too. - // TODO(rsc): After fixing SHRQ, check a->index != 0 too. - case TYPE_REG: - if a.Scale != 0 || a.Name != 0 || a.Sym != nil { - break - } - return - - case TYPE_ADDR: - if a.Val != nil { - break - } - if a.Reg == 0 && a.Index == 0 && a.Scale == 0 && a.Name == 0 && a.Sym == nil { - ctxt.Diag("argument is TYPE_ADDR, should be TYPE_CONST, in %v", p) - } - return - - case TYPE_SHIFT: - if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil { - break - } - return - - case TYPE_REGREG: - if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil { - break - } - return - - case TYPE_REGREG2: - return - - case TYPE_REGLIST: - return - - // Expect sym and name to be set, nothing else. - // Technically more is allowed, but this is only used for *name(SB). - case TYPE_INDIR: - if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name == 0 || a.Offset != 0 || a.Sym == nil || a.Val != nil { - break - } - return - } - - ctxt.Diag("invalid encoding for argument %v", p) -} - -func linkpatch(ctxt *Link, sym *LSym) { - var c int32 - var name string - var q *Prog - - ctxt.Cursym = sym - - for p := sym.Text; p != nil; p = p.Link { - checkaddr(ctxt, p, &p.From) - if p.From3 != nil { - checkaddr(ctxt, p, p.From3) - } - checkaddr(ctxt, p, &p.To) - - if ctxt.Arch.Progedit != nil { - ctxt.Arch.Progedit(ctxt, p) - } - if p.To.Type != TYPE_BRANCH { - continue - } - if p.To.Val != nil { - // TODO: Remove To.Val.(*Prog) in favor of p->pcond. - p.Pcond = p.To.Val.(*Prog) - continue - } - - if p.To.Sym != nil { - continue - } - c = int32(p.To.Offset) - for q = sym.Text; q != nil; { - if int64(c) == q.Pc { - break - } - if q.Forwd != nil && int64(c) >= q.Forwd.Pc { - q = q.Forwd - } else { - q = q.Link - } - } - - if q == nil { - name = "" - if p.To.Sym != nil { - name = p.To.Sym.Name - } - ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name) - p.To.Type = TYPE_NONE - } - - p.To.Val = q - p.Pcond = q - } - - if ctxt.Flag_optimize { - for p := sym.Text; p != nil; p = p.Link { - if p.Pcond != nil { - p.Pcond = brloop(ctxt, p.Pcond) - if p.Pcond != nil { - if p.To.Type == TYPE_BRANCH { - p.To.Offset = p.Pcond.Pc - } - } - } - } - } -} diff --git a/vendor/github.com/google/gops/internal/obj/pcln.go b/vendor/github.com/google/gops/internal/obj/pcln.go deleted file mode 100644 index d9893e42..00000000 --- a/vendor/github.com/google/gops/internal/obj/pcln.go +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2013 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 obj - -import "log" - -func addvarint(ctxt *Link, d *Pcdata, val uint32) { - var v uint32 - for v = val; v >= 0x80; v >>= 7 { - d.P = append(d.P, uint8(v|0x80)) - } - d.P = append(d.P, uint8(v)) -} - -// funcpctab writes to dst a pc-value table mapping the code in func to the values -// returned by valfunc parameterized by arg. The invocation of valfunc to update the -// current value is, for each p, -// -// val = valfunc(func, val, p, 0, arg); -// record val as value at p->pc; -// val = valfunc(func, val, p, 1, arg); -// -// where func is the function, val is the current value, p is the instruction being -// considered, and arg can be used to further parameterize valfunc. -func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) { - // To debug a specific function, uncomment lines and change name. - dbg := 0 - - //if func_.Name == "main.main" || desc == "pctospadj" { - // dbg = 1 - //} - - ctxt.Debugpcln += int32(dbg) - - dst.P = dst.P[:0] - - if ctxt.Debugpcln != 0 { - ctxt.Logf("funcpctab %s [valfunc=%s]\n", func_.Name, desc) - } - - val := int32(-1) - oldval := val - if func_.Text == nil { - ctxt.Debugpcln -= int32(dbg) - return - } - - pc := func_.Text.Pc - - if ctxt.Debugpcln != 0 { - ctxt.Logf("%6x %6d %v\n", uint64(pc), val, func_.Text) - } - - started := int32(0) - var delta uint32 - for p := func_.Text; p != nil; p = p.Link { - // Update val. If it's not changing, keep going. - val = valfunc(ctxt, func_, val, p, 0, arg) - - if val == oldval && started != 0 { - val = valfunc(ctxt, func_, val, p, 1, arg) - if ctxt.Debugpcln != 0 { - ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p) - } - continue - } - - // If the pc of the next instruction is the same as the - // pc of this instruction, this instruction is not a real - // instruction. Keep going, so that we only emit a delta - // for a true instruction boundary in the program. - if p.Link != nil && p.Link.Pc == p.Pc { - val = valfunc(ctxt, func_, val, p, 1, arg) - if ctxt.Debugpcln != 0 { - ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p) - } - continue - } - - // The table is a sequence of (value, pc) pairs, where each - // pair states that the given value is in effect from the current position - // up to the given pc, which becomes the new current position. - // To generate the table as we scan over the program instructions, - // we emit a "(value" when pc == func->value, and then - // each time we observe a change in value we emit ", pc) (value". - // When the scan is over, we emit the closing ", pc)". - // - // The table is delta-encoded. The value deltas are signed and - // transmitted in zig-zag form, where a complement bit is placed in bit 0, - // and the pc deltas are unsigned. Both kinds of deltas are sent - // as variable-length little-endian base-128 integers, - // where the 0x80 bit indicates that the integer continues. - - if ctxt.Debugpcln != 0 { - ctxt.Logf("%6x %6d %v\n", uint64(p.Pc), val, p) - } - - if started != 0 { - addvarint(ctxt, dst, uint32((p.Pc-pc)/int64(ctxt.Arch.MinLC))) - pc = p.Pc - } - - delta = uint32(val) - uint32(oldval) - if delta>>31 != 0 { - delta = 1 | ^(delta << 1) - } else { - delta <<= 1 - } - addvarint(ctxt, dst, delta) - oldval = val - started = 1 - val = valfunc(ctxt, func_, val, p, 1, arg) - } - - if started != 0 { - if ctxt.Debugpcln != 0 { - ctxt.Logf("%6x done\n", uint64(func_.Text.Pc+func_.Size)) - } - addvarint(ctxt, dst, uint32((func_.Size-pc)/int64(ctxt.Arch.MinLC))) - addvarint(ctxt, dst, 0) // terminator - } - - if ctxt.Debugpcln != 0 { - ctxt.Logf("wrote %d bytes to %p\n", len(dst.P), dst) - for i := 0; i < len(dst.P); i++ { - ctxt.Logf(" %02x", dst.P[i]) - } - ctxt.Logf("\n") - } - - ctxt.Debugpcln -= int32(dbg) -} - -// pctofileline computes either the file number (arg == 0) -// or the line number (arg == 1) to use at p. -// Because p->lineno applies to p, phase == 0 (before p) -// takes care of the update. -func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { - if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Lineno == 0 || phase == 1 { - return oldval - } - f, l := linkgetline(ctxt, p.Lineno) - if f == nil { - // print("getline failed for %s %v\n", ctxt->cursym->name, p); - return oldval - } - - if arg == nil { - return l - } - pcln := arg.(*Pcln) - - if f == pcln.Lastfile { - return int32(pcln.Lastindex) - } - - for i, file := range pcln.File { - if file == f { - pcln.Lastfile = f - pcln.Lastindex = i - return int32(i) - } - } - i := len(pcln.File) - pcln.File = append(pcln.File, f) - pcln.Lastfile = f - pcln.Lastindex = i - return int32(i) -} - -// pctospadj computes the sp adjustment in effect. -// It is oldval plus any adjustment made by p itself. -// The adjustment by p takes effect only after p, so we -// apply the change during phase == 1. -func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { - if oldval == -1 { // starting - oldval = 0 - } - if phase == 0 { - return oldval - } - if oldval+p.Spadj < -10000 || oldval+p.Spadj > 1100000000 { - ctxt.Diag("overflow in spadj: %d + %d = %d", oldval, p.Spadj, oldval+p.Spadj) - log.Fatalf("bad code") - } - - return oldval + p.Spadj -} - -// pctopcdata computes the pcdata value in effect at p. -// A PCDATA instruction sets the value in effect at future -// non-PCDATA instructions. -// Since PCDATA instructions have no width in the final code, -// it does not matter which phase we use for the update. -func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { - if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) { - return oldval - } - if int64(int32(p.To.Offset)) != p.To.Offset { - ctxt.Diag("overflow in PCDATA instruction: %v", p) - log.Fatalf("bad code") - } - - return int32(p.To.Offset) -} - -func linkpcln(ctxt *Link, cursym *LSym) { - ctxt.Cursym = cursym - - pcln := new(Pcln) - cursym.Pcln = pcln - - npcdata := 0 - nfuncdata := 0 - for p := cursym.Text; p != nil; p = p.Link { - // Find the highest ID of any used PCDATA table. This ignores PCDATA table - // that consist entirely of "-1", since that's the assumed default value. - // From.Offset is table ID - // To.Offset is data - if p.As == APCDATA && p.From.Offset >= int64(npcdata) && p.To.Offset != -1 { // ignore -1 as we start at -1, if we only see -1, nothing changed - npcdata = int(p.From.Offset + 1) - } - // Find the highest ID of any FUNCDATA table. - // From.Offset is table ID - if p.As == AFUNCDATA && p.From.Offset >= int64(nfuncdata) { - nfuncdata = int(p.From.Offset + 1) - } - } - - pcln.Pcdata = make([]Pcdata, npcdata) - pcln.Pcdata = pcln.Pcdata[:npcdata] - pcln.Funcdata = make([]*LSym, nfuncdata) - pcln.Funcdataoff = make([]int64, nfuncdata) - pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata] - - funcpctab(ctxt, &pcln.Pcsp, cursym, "pctospadj", pctospadj, nil) - funcpctab(ctxt, &pcln.Pcfile, cursym, "pctofile", pctofileline, pcln) - funcpctab(ctxt, &pcln.Pcline, cursym, "pctoline", pctofileline, nil) - - // tabulate which pc and func data we have. - havepc := make([]uint32, (npcdata+31)/32) - havefunc := make([]uint32, (nfuncdata+31)/32) - for p := cursym.Text; p != nil; p = p.Link { - if p.As == AFUNCDATA { - if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 { - ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset) - } - havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) - } - - if p.As == APCDATA && p.To.Offset != -1 { - havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) - } - } - - // pcdata. - for i := 0; i < npcdata; i++ { - if (havepc[i/32]>>uint(i%32))&1 == 0 { - continue - } - funcpctab(ctxt, &pcln.Pcdata[i], cursym, "pctopcdata", pctopcdata, interface{}(uint32(i))) - } - - // funcdata - if nfuncdata > 0 { - var i int - for p := cursym.Text; p != nil; p = p.Link { - if p.As == AFUNCDATA { - i = int(p.From.Offset) - pcln.Funcdataoff[i] = p.To.Offset - if p.To.Type != TYPE_CONST { - // TODO: Dedup. - //funcdata_bytes += p->to.sym->size; - pcln.Funcdata[i] = p.To.Sym - } - } - } - } -} diff --git a/vendor/github.com/google/gops/internal/obj/plist.go b/vendor/github.com/google/gops/internal/obj/plist.go deleted file mode 100644 index 804ea637..00000000 --- a/vendor/github.com/google/gops/internal/obj/plist.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2013 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 obj - -import ( - "fmt" - "log" - "strings" -) - -type Plist struct { - Firstpc *Prog -} - -/* - * start a new Prog list. - */ -func Linknewplist(ctxt *Link) *Plist { - pl := new(Plist) - ctxt.Plists = append(ctxt.Plists, pl) - return pl -} - -func Flushplist(ctxt *Link) { - flushplist(ctxt, ctxt.Debugasm == 0) -} -func FlushplistNoFree(ctxt *Link) { - flushplist(ctxt, false) -} -func flushplist(ctxt *Link, freeProgs bool) { - // Build list of symbols, and assign instructions to lists. - // Ignore ctxt->plist boundaries. There are no guarantees there, - // and the assemblers just use one big list. - var curtext *LSym - var etext *Prog - var text []*LSym - - for _, pl := range ctxt.Plists { - var plink *Prog - for p := pl.Firstpc; p != nil; p = plink { - if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 { - fmt.Printf("obj: %v\n", p) - } - plink = p.Link - p.Link = nil - - switch p.As { - case AEND: - continue - - case ATYPE: - // Assume each TYPE instruction describes - // a different local variable or parameter, - // so no dedup. - // Using only the TYPE instructions means - // that we discard location information about local variables - // in C and assembly functions; that information is inferred - // from ordinary references, because there are no TYPE - // instructions there. Without the type information, gdb can't - // use the locations, so we don't bother to save them. - // If something else could use them, we could arrange to - // preserve them. - if curtext == nil { - continue - } - a := new(Auto) - a.Asym = p.From.Sym - a.Aoffset = int32(p.From.Offset) - a.Name = int16(p.From.Name) - a.Gotype = p.To.Sym - a.Link = curtext.Autom - curtext.Autom = a - continue - - case ATEXT: - s := p.From.Sym - if s == nil { - // func _() { } - curtext = nil - - continue - } - - if s.Text != nil { - log.Fatalf("duplicate TEXT for %s", s.Name) - } - if s.OnList() { - log.Fatalf("symbol %s listed multiple times", s.Name) - } - s.Set(AttrOnList, true) - text = append(text, s) - flag := int(p.From3Offset()) - if flag&DUPOK != 0 { - s.Set(AttrDuplicateOK, true) - } - if flag&NOSPLIT != 0 { - s.Set(AttrNoSplit, true) - } - if flag&REFLECTMETHOD != 0 { - s.Set(AttrReflectMethod, true) - } - s.Type = STEXT - s.Text = p - etext = p - curtext = s - continue - - case AFUNCDATA: - // Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information. - if curtext == nil { // func _() {} - continue - } - if p.To.Sym.Name == "go_args_stackmap" { - if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps { - ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps") - } - p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version)) - } - - } - - if curtext == nil { - etext = nil - continue - } - etext.Link = p - etext = p - } - } - - // Add reference to Go arguments for C or assembly functions without them. - for _, s := range text { - if !strings.HasPrefix(s.Name, "\"\".") { - continue - } - found := false - var p *Prog - for p = s.Text; p != nil; p = p.Link { - if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps { - found = true - break - } - } - - if !found { - p = Appendp(ctxt, s.Text) - p.As = AFUNCDATA - p.From.Type = TYPE_CONST - p.From.Offset = FUNCDATA_ArgsPointerMaps - p.To.Type = TYPE_MEM - p.To.Name = NAME_EXTERN - p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version)) - } - } - - // Turn functions into machine code images. - for _, s := range text { - mkfwd(s) - linkpatch(ctxt, s) - if ctxt.Flag_optimize { - ctxt.Arch.Follow(ctxt, s) - } - ctxt.Arch.Preprocess(ctxt, s) - ctxt.Arch.Assemble(ctxt, s) - fieldtrack(ctxt, s) - linkpcln(ctxt, s) - if freeProgs { - s.Text = nil - } - } - - // Add to running list in ctxt. - ctxt.Text = append(ctxt.Text, text...) - ctxt.Data = append(ctxt.Data, gendwarf(ctxt, text)...) - ctxt.Plists = nil - ctxt.Curp = nil - if freeProgs { - ctxt.freeProgs() - } -} - -func (ctxt *Link) Globl(s *LSym, size int64, flag int) { - if s.SeenGlobl() { - fmt.Printf("duplicate %v\n", s) - } - s.Set(AttrSeenGlobl, true) - if s.OnList() { - log.Fatalf("symbol %s listed multiple times", s.Name) - } - s.Set(AttrOnList, true) - ctxt.Data = append(ctxt.Data, s) - s.Size = size - if s.Type == 0 || s.Type == SXREF { - s.Type = SBSS - } - if flag&DUPOK != 0 { - s.Set(AttrDuplicateOK, true) - } - if flag&RODATA != 0 { - s.Type = SRODATA - } else if flag&NOPTR != 0 { - s.Type = SNOPTRBSS - } else if flag&TLSBSS != 0 { - s.Type = STLSBSS - } -} diff --git a/vendor/github.com/google/gops/internal/obj/ppc64/a.out.go b/vendor/github.com/google/gops/internal/obj/ppc64/a.out.go deleted file mode 100644 index 48d8ed15..00000000 --- a/vendor/github.com/google/gops/internal/obj/ppc64/a.out.go +++ /dev/null @@ -1,941 +0,0 @@ -// cmd/9c/9.out.h from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package ppc64 - -import "github.com/google/gops/internal/obj" - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p ppc64 - -/* - * powerpc 64 - */ -const ( - NSNAME = 8 - NSYM = 50 - NREG = 32 /* number of general registers */ - NFREG = 32 /* number of floating point registers */ -) - -const ( - /* RBasePPC64 = 4096 */ - /* R0=4096 ... R31=4127 */ - REG_R0 = obj.RBasePPC64 + iota - REG_R1 - REG_R2 - REG_R3 - REG_R4 - REG_R5 - REG_R6 - REG_R7 - REG_R8 - REG_R9 - REG_R10 - REG_R11 - REG_R12 - REG_R13 - REG_R14 - REG_R15 - REG_R16 - REG_R17 - REG_R18 - REG_R19 - REG_R20 - REG_R21 - REG_R22 - REG_R23 - REG_R24 - REG_R25 - REG_R26 - REG_R27 - REG_R28 - REG_R29 - REG_R30 - REG_R31 - - /* F0=4128 ... F31=4159 */ - REG_F0 - REG_F1 - REG_F2 - REG_F3 - REG_F4 - REG_F5 - REG_F6 - REG_F7 - REG_F8 - REG_F9 - REG_F10 - REG_F11 - REG_F12 - REG_F13 - REG_F14 - REG_F15 - REG_F16 - REG_F17 - REG_F18 - REG_F19 - REG_F20 - REG_F21 - REG_F22 - REG_F23 - REG_F24 - REG_F25 - REG_F26 - REG_F27 - REG_F28 - REG_F29 - REG_F30 - REG_F31 - - /* V0=4160 ... V31=4191 */ - REG_V0 - REG_V1 - REG_V2 - REG_V3 - REG_V4 - REG_V5 - REG_V6 - REG_V7 - REG_V8 - REG_V9 - REG_V10 - REG_V11 - REG_V12 - REG_V13 - REG_V14 - REG_V15 - REG_V16 - REG_V17 - REG_V18 - REG_V19 - REG_V20 - REG_V21 - REG_V22 - REG_V23 - REG_V24 - REG_V25 - REG_V26 - REG_V27 - REG_V28 - REG_V29 - REG_V30 - REG_V31 - - /* VS0=4192 ... VS63=4255 */ - REG_VS0 - REG_VS1 - REG_VS2 - REG_VS3 - REG_VS4 - REG_VS5 - REG_VS6 - REG_VS7 - REG_VS8 - REG_VS9 - REG_VS10 - REG_VS11 - REG_VS12 - REG_VS13 - REG_VS14 - REG_VS15 - REG_VS16 - REG_VS17 - REG_VS18 - REG_VS19 - REG_VS20 - REG_VS21 - REG_VS22 - REG_VS23 - REG_VS24 - REG_VS25 - REG_VS26 - REG_VS27 - REG_VS28 - REG_VS29 - REG_VS30 - REG_VS31 - REG_VS32 - REG_VS33 - REG_VS34 - REG_VS35 - REG_VS36 - REG_VS37 - REG_VS38 - REG_VS39 - REG_VS40 - REG_VS41 - REG_VS42 - REG_VS43 - REG_VS44 - REG_VS45 - REG_VS46 - REG_VS47 - REG_VS48 - REG_VS49 - REG_VS50 - REG_VS51 - REG_VS52 - REG_VS53 - REG_VS54 - REG_VS55 - REG_VS56 - REG_VS57 - REG_VS58 - REG_VS59 - REG_VS60 - REG_VS61 - REG_VS62 - REG_VS63 - - REG_CR0 - REG_CR1 - REG_CR2 - REG_CR3 - REG_CR4 - REG_CR5 - REG_CR6 - REG_CR7 - - REG_MSR - REG_FPSCR - REG_CR - - REG_SPECIAL = REG_CR0 - - REG_SPR0 = obj.RBasePPC64 + 1024 // first of 1024 registers - REG_DCR0 = obj.RBasePPC64 + 2048 // first of 1024 registers - - REG_XER = REG_SPR0 + 1 - REG_LR = REG_SPR0 + 8 - REG_CTR = REG_SPR0 + 9 - - REGZERO = REG_R0 /* set to zero */ - REGSP = REG_R1 - REGSB = REG_R2 - REGRET = REG_R3 - REGARG = -1 /* -1 disables passing the first argument in register */ - REGRT1 = REG_R3 /* reserved for runtime, duffzero and duffcopy */ - REGRT2 = REG_R4 /* reserved for runtime, duffcopy */ - REGMIN = REG_R7 /* register variables allocated from here to REGMAX */ - REGCTXT = REG_R11 /* context for closures */ - REGTLS = REG_R13 /* C ABI TLS base pointer */ - REGMAX = REG_R27 - REGEXT = REG_R30 /* external registers allocated from here down */ - REGG = REG_R30 /* G */ - REGTMP = REG_R31 /* used by the linker */ - FREGRET = REG_F0 - FREGMIN = REG_F17 /* first register variable */ - FREGMAX = REG_F26 /* last register variable for 9g only */ - FREGEXT = REG_F26 /* first external register */ -) - -/* - * GENERAL: - * - * compiler allocates R3 up as temps - * compiler allocates register variables R7-R27 - * compiler allocates external registers R30 down - * - * compiler allocates register variables F17-F26 - * compiler allocates external registers F26 down - */ -const ( - BIG = 32768 - 8 -) - -const ( - /* mark flags */ - LABEL = 1 << 0 - LEAF = 1 << 1 - FLOAT = 1 << 2 - BRANCH = 1 << 3 - LOAD = 1 << 4 - FCMP = 1 << 5 - SYNC = 1 << 6 - LIST = 1 << 7 - FOLL = 1 << 8 - NOSCHED = 1 << 9 -) - -// Values for use in branch instruction BC -// BC B0,BI,label -// BO is type of branch + likely bits described below -// BI is CR value + branch type -// ex: BEQ CR2,label is BC 12,10,label -// 12 = BO_BCR -// 10 = BI_CR2 + BI_EQ - -const ( - BI_CR0 = 0 - BI_CR1 = 4 - BI_CR2 = 8 - BI_CR3 = 12 - BI_CR4 = 16 - BI_CR5 = 20 - BI_CR6 = 24 - BI_CR7 = 28 - BI_LT = 0 - BI_GT = 1 - BI_EQ = 2 - BI_OVF = 3 -) - -// Values for the BO field. Add the branch type to -// the likely bits, if a likely setting is known. -// If branch likely or unlikely is not known, don't set it. -// e.g. branch on cr+likely = 15 - -const ( - BO_BCTR = 16 // branch on ctr value - BO_BCR = 12 // branch on cr value - BO_BCRBCTR = 8 // branch on ctr and cr value - BO_NOTBCR = 4 // branch on not cr value - BO_UNLIKELY = 2 // value for unlikely - BO_LIKELY = 3 // value for likely -) - -// Bit settings from the CR - -const ( - C_COND_LT = iota // 0 result is negative - C_COND_GT // 1 result is positive - C_COND_EQ // 2 result is zero - C_COND_SO // 3 summary overflow or FP compare w/ NaN -) - -const ( - C_NONE = iota - C_REG - C_FREG - C_VREG - C_VSREG - C_CREG - C_SPR /* special processor register */ - C_ZCON - C_SCON /* 16 bit signed */ - C_UCON /* 32 bit signed, low 16 bits 0 */ - C_ADDCON /* -0x8000 <= v < 0 */ - C_ANDCON /* 0 < v <= 0xFFFF */ - C_LCON /* other 32 */ - C_DCON /* other 64 (could subdivide further) */ - C_SACON /* $n(REG) where n <= int16 */ - C_SECON - C_LACON /* $n(REG) where int16 < n <= int32 */ - C_LECON - C_DACON /* $n(REG) where int32 < n */ - C_SBRA - C_LBRA - C_LBRAPIC - C_SAUTO - C_LAUTO - C_SEXT - C_LEXT - C_ZOREG // conjecture: either (1) register + zeroed offset, or (2) "R0" implies zero or C_REG - C_SOREG // register + signed offset - C_LOREG - C_FPSCR - C_MSR - C_XER - C_LR - C_CTR - C_ANY - C_GOK - C_ADDR - C_GOTADDR - C_TLS_LE - C_TLS_IE - C_TEXTSIZE - - C_NCLASS /* must be the last */ -) - -const ( - AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota - AADDCC - AADDV - AADDVCC - AADDC - AADDCCC - AADDCV - AADDCVCC - AADDME - AADDMECC - AADDMEVCC - AADDMEV - AADDE - AADDECC - AADDEVCC - AADDEV - AADDZE - AADDZECC - AADDZEVCC - AADDZEV - AAND - AANDCC - AANDN - AANDNCC - ABC - ABCL - ABEQ - ABGE // not LT = G/E/U - ABGT - ABLE // not GT = L/E/U - ABLT - ABNE // not EQ = L/G/U - ABVC // Unordered-clear - ABVS // Unordered-set - ACMP - ACMPU - ACNTLZW - ACNTLZWCC - ACRAND - ACRANDN - ACREQV - ACRNAND - ACRNOR - ACROR - ACRORN - ACRXOR - ADIVW - ADIVWCC - ADIVWVCC - ADIVWV - ADIVWU - ADIVWUCC - ADIVWUVCC - ADIVWUV - AEQV - AEQVCC - AEXTSB - AEXTSBCC - AEXTSH - AEXTSHCC - AFABS - AFABSCC - AFADD - AFADDCC - AFADDS - AFADDSCC - AFCMPO - AFCMPU - AFCTIW - AFCTIWCC - AFCTIWZ - AFCTIWZCC - AFDIV - AFDIVCC - AFDIVS - AFDIVSCC - AFMADD - AFMADDCC - AFMADDS - AFMADDSCC - AFMOVD - AFMOVDCC - AFMOVDU - AFMOVS - AFMOVSU - AFMOVSX - AFMOVSZ - AFMSUB - AFMSUBCC - AFMSUBS - AFMSUBSCC - AFMUL - AFMULCC - AFMULS - AFMULSCC - AFNABS - AFNABSCC - AFNEG - AFNEGCC - AFNMADD - AFNMADDCC - AFNMADDS - AFNMADDSCC - AFNMSUB - AFNMSUBCC - AFNMSUBS - AFNMSUBSCC - AFRSP - AFRSPCC - AFSUB - AFSUBCC - AFSUBS - AFSUBSCC - AISEL - AMOVMW - ALBAR - ALSW - ALWAR - ALWSYNC - AMOVDBR - AMOVWBR - AMOVB - AMOVBU - AMOVBZ - AMOVBZU - AMOVH - AMOVHBR - AMOVHU - AMOVHZ - AMOVHZU - AMOVW - AMOVWU - AMOVFL - AMOVCRFS - AMTFSB0 - AMTFSB0CC - AMTFSB1 - AMTFSB1CC - AMULHW - AMULHWCC - AMULHWU - AMULHWUCC - AMULLW - AMULLWCC - AMULLWVCC - AMULLWV - ANAND - ANANDCC - ANEG - ANEGCC - ANEGVCC - ANEGV - ANOR - ANORCC - AOR - AORCC - AORN - AORNCC - AREM - AREMCC - AREMV - AREMVCC - AREMU - AREMUCC - AREMUV - AREMUVCC - ARFI - ARLWMI - ARLWMICC - ARLWNM - ARLWNMCC - ASLW - ASLWCC - ASRW - ASRAW - ASRAWCC - ASRWCC - ASTBCCC - ASTSW - ASTWCCC - ASUB - ASUBCC - ASUBVCC - ASUBC - ASUBCCC - ASUBCV - ASUBCVCC - ASUBME - ASUBMECC - ASUBMEVCC - ASUBMEV - ASUBV - ASUBE - ASUBECC - ASUBEV - ASUBEVCC - ASUBZE - ASUBZECC - ASUBZEVCC - ASUBZEV - ASYNC - AXOR - AXORCC - - ADCBF - ADCBI - ADCBST - ADCBT - ADCBTST - ADCBZ - AECIWX - AECOWX - AEIEIO - AICBI - AISYNC - APTESYNC - ATLBIE - ATLBIEL - ATLBSYNC - ATW - - ASYSCALL - AWORD - - ARFCI - - /* optional on 32-bit */ - AFRES - AFRESCC - AFRIM - AFRIMCC - AFRIP - AFRIPCC - AFRIZ - AFRIZCC - AFRSQRTE - AFRSQRTECC - AFSEL - AFSELCC - AFSQRT - AFSQRTCC - AFSQRTS - AFSQRTSCC - - /* 64-bit */ - - ACNTLZD - ACNTLZDCC - ACMPW /* CMP with L=0 */ - ACMPWU - ADIVD - ADIVDCC - ADIVDE - ADIVDECC - ADIVDEU - ADIVDEUCC - ADIVDVCC - ADIVDV - ADIVDU - ADIVDUCC - ADIVDUVCC - ADIVDUV - AEXTSW - AEXTSWCC - /* AFCFIW; AFCFIWCC */ - AFCFID - AFCFIDCC - AFCFIDU - AFCFIDUCC - AFCTID - AFCTIDCC - AFCTIDZ - AFCTIDZCC - ALDAR - AMOVD - AMOVDU - AMOVWZ - AMOVWZU - AMULHD - AMULHDCC - AMULHDU - AMULHDUCC - AMULLD - AMULLDCC - AMULLDVCC - AMULLDV - ARFID - ARLDMI - ARLDMICC - ARLDIMI - ARLDIMICC - ARLDC - ARLDCCC - ARLDCR - ARLDCRCC - ARLDICR - ARLDICRCC - ARLDCL - ARLDCLCC - ARLDICL - ARLDICLCC - ASLBIA - ASLBIE - ASLBMFEE - ASLBMFEV - ASLBMTE - ASLD - ASLDCC - ASRD - ASRAD - ASRADCC - ASRDCC - ASTDCCC - ATD - - /* 64-bit pseudo operation */ - ADWORD - AREMD - AREMDCC - AREMDV - AREMDVCC - AREMDU - AREMDUCC - AREMDUV - AREMDUVCC - - /* more 64-bit operations */ - AHRFID - - /* Vector */ - ALV - ALVEBX - ALVEHX - ALVEWX - ALVX - ALVXL - ALVSL - ALVSR - ASTV - ASTVEBX - ASTVEHX - ASTVEWX - ASTVX - ASTVXL - AVAND - AVANDL - AVANDC - AVNAND - AVOR - AVORL - AVORC - AVNOR - AVXOR - AVEQV - AVADDUM - AVADDUBM - AVADDUHM - AVADDUWM - AVADDUDM - AVADDUQM - AVADDCU - AVADDCUQ - AVADDCUW - AVADDUS - AVADDUBS - AVADDUHS - AVADDUWS - AVADDSS - AVADDSBS - AVADDSHS - AVADDSWS - AVADDE - AVADDEUQM - AVADDECUQ - AVSUBUM - AVSUBUBM - AVSUBUHM - AVSUBUWM - AVSUBUDM - AVSUBUQM - AVSUBCU - AVSUBCUQ - AVSUBCUW - AVSUBUS - AVSUBUBS - AVSUBUHS - AVSUBUWS - AVSUBSS - AVSUBSBS - AVSUBSHS - AVSUBSWS - AVSUBE - AVSUBEUQM - AVSUBECUQ - AVR - AVRLB - AVRLH - AVRLW - AVRLD - AVS - AVSLB - AVSLH - AVSLW - AVSL - AVSLO - AVSRB - AVSRH - AVSRW - AVSR - AVSRO - AVSLD - AVSRD - AVSA - AVSRAB - AVSRAH - AVSRAW - AVSRAD - AVSOI - AVSLDOI - AVCLZ - AVCLZB - AVCLZH - AVCLZW - AVCLZD - AVPOPCNT - AVPOPCNTB - AVPOPCNTH - AVPOPCNTW - AVPOPCNTD - AVCMPEQ - AVCMPEQUB - AVCMPEQUBCC - AVCMPEQUH - AVCMPEQUHCC - AVCMPEQUW - AVCMPEQUWCC - AVCMPEQUD - AVCMPEQUDCC - AVCMPGT - AVCMPGTUB - AVCMPGTUBCC - AVCMPGTUH - AVCMPGTUHCC - AVCMPGTUW - AVCMPGTUWCC - AVCMPGTUD - AVCMPGTUDCC - AVCMPGTSB - AVCMPGTSBCC - AVCMPGTSH - AVCMPGTSHCC - AVCMPGTSW - AVCMPGTSWCC - AVCMPGTSD - AVCMPGTSDCC - AVPERM - AVSEL - AVSPLT - AVSPLTB - AVSPLTH - AVSPLTW - AVSPLTI - AVSPLTISB - AVSPLTISH - AVSPLTISW - AVCIPH - AVCIPHER - AVCIPHERLAST - AVNCIPH - AVNCIPHER - AVNCIPHERLAST - AVSBOX - AVSHASIGMA - AVSHASIGMAW - AVSHASIGMAD - - /* VSX */ - ALXV - ALXVD2X - ALXVDSX - ALXVW4X - ASTXV - ASTXVD2X - ASTXVW4X - ALXS - ALXSDX - ASTXS - ASTXSDX - ALXSI - ALXSIWAX - ALXSIWZX - ASTXSI - ASTXSIWX - AMFVSR - AMFVSRD - AMFVSRWZ - AMTVSR - AMTVSRD - AMTVSRWA - AMTVSRWZ - AXXLAND - AXXLANDQ - AXXLANDC - AXXLEQV - AXXLNAND - AXXLOR - AXXLORC - AXXLNOR - AXXLORQ - AXXLXOR - AXXSEL - AXXMRG - AXXMRGHW - AXXMRGLW - AXXSPLT - AXXSPLTW - AXXPERM - AXXPERMDI - AXXSI - AXXSLDWI - AXSCV - AXSCVDPSP - AXSCVSPDP - AXSCVDPSPN - AXSCVSPDPN - AXVCV - AXVCVDPSP - AXVCVSPDP - AXSCVX - AXSCVDPSXDS - AXSCVDPSXWS - AXSCVDPUXDS - AXSCVDPUXWS - AXSCVXP - AXSCVSXDDP - AXSCVUXDDP - AXSCVSXDSP - AXSCVUXDSP - AXVCVX - AXVCVDPSXDS - AXVCVDPSXWS - AXVCVDPUXDS - AXVCVDPUXWS - AXVCVSPSXDS - AXVCVSPSXWS - AXVCVSPUXDS - AXVCVSPUXWS - AXVCVXP - AXVCVSXDDP - AXVCVSXWDP - AXVCVUXDDP - AXVCVUXWDP - AXVCVSXDSP - AXVCVSXWSP - AXVCVUXDSP - AXVCVUXWSP - - ALAST - - // aliases - ABR = obj.AJMP - ABL = obj.ACALL -) diff --git a/vendor/github.com/google/gops/internal/obj/ppc64/anames.go b/vendor/github.com/google/gops/internal/obj/ppc64/anames.go deleted file mode 100644 index 12aca66a..00000000 --- a/vendor/github.com/google/gops/internal/obj/ppc64/anames.go +++ /dev/null @@ -1,549 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p ppc64 -// Do not edit. - -package ppc64 - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "ADD", - "ADDCC", - "ADDV", - "ADDVCC", - "ADDC", - "ADDCCC", - "ADDCV", - "ADDCVCC", - "ADDME", - "ADDMECC", - "ADDMEVCC", - "ADDMEV", - "ADDE", - "ADDECC", - "ADDEVCC", - "ADDEV", - "ADDZE", - "ADDZECC", - "ADDZEVCC", - "ADDZEV", - "AND", - "ANDCC", - "ANDN", - "ANDNCC", - "BC", - "BCL", - "BEQ", - "BGE", - "BGT", - "BLE", - "BLT", - "BNE", - "BVC", - "BVS", - "CMP", - "CMPU", - "CNTLZW", - "CNTLZWCC", - "CRAND", - "CRANDN", - "CREQV", - "CRNAND", - "CRNOR", - "CROR", - "CRORN", - "CRXOR", - "DIVW", - "DIVWCC", - "DIVWVCC", - "DIVWV", - "DIVWU", - "DIVWUCC", - "DIVWUVCC", - "DIVWUV", - "EQV", - "EQVCC", - "EXTSB", - "EXTSBCC", - "EXTSH", - "EXTSHCC", - "FABS", - "FABSCC", - "FADD", - "FADDCC", - "FADDS", - "FADDSCC", - "FCMPO", - "FCMPU", - "FCTIW", - "FCTIWCC", - "FCTIWZ", - "FCTIWZCC", - "FDIV", - "FDIVCC", - "FDIVS", - "FDIVSCC", - "FMADD", - "FMADDCC", - "FMADDS", - "FMADDSCC", - "FMOVD", - "FMOVDCC", - "FMOVDU", - "FMOVS", - "FMOVSU", - "FMOVSX", - "FMOVSZ", - "FMSUB", - "FMSUBCC", - "FMSUBS", - "FMSUBSCC", - "FMUL", - "FMULCC", - "FMULS", - "FMULSCC", - "FNABS", - "FNABSCC", - "FNEG", - "FNEGCC", - "FNMADD", - "FNMADDCC", - "FNMADDS", - "FNMADDSCC", - "FNMSUB", - "FNMSUBCC", - "FNMSUBS", - "FNMSUBSCC", - "FRSP", - "FRSPCC", - "FSUB", - "FSUBCC", - "FSUBS", - "FSUBSCC", - "ISEL", - "MOVMW", - "LBAR", - "LSW", - "LWAR", - "LWSYNC", - "MOVDBR", - "MOVWBR", - "MOVB", - "MOVBU", - "MOVBZ", - "MOVBZU", - "MOVH", - "MOVHBR", - "MOVHU", - "MOVHZ", - "MOVHZU", - "MOVW", - "MOVWU", - "MOVFL", - "MOVCRFS", - "MTFSB0", - "MTFSB0CC", - "MTFSB1", - "MTFSB1CC", - "MULHW", - "MULHWCC", - "MULHWU", - "MULHWUCC", - "MULLW", - "MULLWCC", - "MULLWVCC", - "MULLWV", - "NAND", - "NANDCC", - "NEG", - "NEGCC", - "NEGVCC", - "NEGV", - "NOR", - "NORCC", - "OR", - "ORCC", - "ORN", - "ORNCC", - "REM", - "REMCC", - "REMV", - "REMVCC", - "REMU", - "REMUCC", - "REMUV", - "REMUVCC", - "RFI", - "RLWMI", - "RLWMICC", - "RLWNM", - "RLWNMCC", - "SLW", - "SLWCC", - "SRW", - "SRAW", - "SRAWCC", - "SRWCC", - "STBCCC", - "STSW", - "STWCCC", - "SUB", - "SUBCC", - "SUBVCC", - "SUBC", - "SUBCCC", - "SUBCV", - "SUBCVCC", - "SUBME", - "SUBMECC", - "SUBMEVCC", - "SUBMEV", - "SUBV", - "SUBE", - "SUBECC", - "SUBEV", - "SUBEVCC", - "SUBZE", - "SUBZECC", - "SUBZEVCC", - "SUBZEV", - "SYNC", - "XOR", - "XORCC", - "DCBF", - "DCBI", - "DCBST", - "DCBT", - "DCBTST", - "DCBZ", - "ECIWX", - "ECOWX", - "EIEIO", - "ICBI", - "ISYNC", - "PTESYNC", - "TLBIE", - "TLBIEL", - "TLBSYNC", - "TW", - "SYSCALL", - "WORD", - "RFCI", - "FRES", - "FRESCC", - "FRIM", - "FRIMCC", - "FRIP", - "FRIPCC", - "FRIZ", - "FRIZCC", - "FRSQRTE", - "FRSQRTECC", - "FSEL", - "FSELCC", - "FSQRT", - "FSQRTCC", - "FSQRTS", - "FSQRTSCC", - "CNTLZD", - "CNTLZDCC", - "CMPW", - "CMPWU", - "DIVD", - "DIVDCC", - "DIVDE", - "DIVDECC", - "DIVDEU", - "DIVDEUCC", - "DIVDVCC", - "DIVDV", - "DIVDU", - "DIVDUCC", - "DIVDUVCC", - "DIVDUV", - "EXTSW", - "EXTSWCC", - "FCFID", - "FCFIDCC", - "FCFIDU", - "FCFIDUCC", - "FCTID", - "FCTIDCC", - "FCTIDZ", - "FCTIDZCC", - "LDAR", - "MOVD", - "MOVDU", - "MOVWZ", - "MOVWZU", - "MULHD", - "MULHDCC", - "MULHDU", - "MULHDUCC", - "MULLD", - "MULLDCC", - "MULLDVCC", - "MULLDV", - "RFID", - "RLDMI", - "RLDMICC", - "RLDIMI", - "RLDIMICC", - "RLDC", - "RLDCCC", - "RLDCR", - "RLDCRCC", - "RLDICR", - "RLDICRCC", - "RLDCL", - "RLDCLCC", - "RLDICL", - "RLDICLCC", - "SLBIA", - "SLBIE", - "SLBMFEE", - "SLBMFEV", - "SLBMTE", - "SLD", - "SLDCC", - "SRD", - "SRAD", - "SRADCC", - "SRDCC", - "STDCCC", - "TD", - "DWORD", - "REMD", - "REMDCC", - "REMDV", - "REMDVCC", - "REMDU", - "REMDUCC", - "REMDUV", - "REMDUVCC", - "HRFID", - "LV", - "LVEBX", - "LVEHX", - "LVEWX", - "LVX", - "LVXL", - "LVSL", - "LVSR", - "STV", - "STVEBX", - "STVEHX", - "STVEWX", - "STVX", - "STVXL", - "VAND", - "VANDL", - "VANDC", - "VNAND", - "VOR", - "VORL", - "VORC", - "VNOR", - "VXOR", - "VEQV", - "VADDUM", - "VADDUBM", - "VADDUHM", - "VADDUWM", - "VADDUDM", - "VADDUQM", - "VADDCU", - "VADDCUQ", - "VADDCUW", - "VADDUS", - "VADDUBS", - "VADDUHS", - "VADDUWS", - "VADDSS", - "VADDSBS", - "VADDSHS", - "VADDSWS", - "VADDE", - "VADDEUQM", - "VADDECUQ", - "VSUBUM", - "VSUBUBM", - "VSUBUHM", - "VSUBUWM", - "VSUBUDM", - "VSUBUQM", - "VSUBCU", - "VSUBCUQ", - "VSUBCUW", - "VSUBUS", - "VSUBUBS", - "VSUBUHS", - "VSUBUWS", - "VSUBSS", - "VSUBSBS", - "VSUBSHS", - "VSUBSWS", - "VSUBE", - "VSUBEUQM", - "VSUBECUQ", - "VR", - "VRLB", - "VRLH", - "VRLW", - "VRLD", - "VS", - "VSLB", - "VSLH", - "VSLW", - "VSL", - "VSLO", - "VSRB", - "VSRH", - "VSRW", - "VSR", - "VSRO", - "VSLD", - "VSRD", - "VSA", - "VSRAB", - "VSRAH", - "VSRAW", - "VSRAD", - "VSOI", - "VSLDOI", - "VCLZ", - "VCLZB", - "VCLZH", - "VCLZW", - "VCLZD", - "VPOPCNT", - "VPOPCNTB", - "VPOPCNTH", - "VPOPCNTW", - "VPOPCNTD", - "VCMPEQ", - "VCMPEQUB", - "VCMPEQUBCC", - "VCMPEQUH", - "VCMPEQUHCC", - "VCMPEQUW", - "VCMPEQUWCC", - "VCMPEQUD", - "VCMPEQUDCC", - "VCMPGT", - "VCMPGTUB", - "VCMPGTUBCC", - "VCMPGTUH", - "VCMPGTUHCC", - "VCMPGTUW", - "VCMPGTUWCC", - "VCMPGTUD", - "VCMPGTUDCC", - "VCMPGTSB", - "VCMPGTSBCC", - "VCMPGTSH", - "VCMPGTSHCC", - "VCMPGTSW", - "VCMPGTSWCC", - "VCMPGTSD", - "VCMPGTSDCC", - "VPERM", - "VSEL", - "VSPLT", - "VSPLTB", - "VSPLTH", - "VSPLTW", - "VSPLTI", - "VSPLTISB", - "VSPLTISH", - "VSPLTISW", - "VCIPH", - "VCIPHER", - "VCIPHERLAST", - "VNCIPH", - "VNCIPHER", - "VNCIPHERLAST", - "VSBOX", - "VSHASIGMA", - "VSHASIGMAW", - "VSHASIGMAD", - "LXV", - "LXVD2X", - "LXVDSX", - "LXVW4X", - "STXV", - "STXVD2X", - "STXVW4X", - "LXS", - "LXSDX", - "STXS", - "STXSDX", - "LXSI", - "LXSIWAX", - "LXSIWZX", - "STXSI", - "STXSIWX", - "MFVSR", - "MFVSRD", - "MFVSRWZ", - "MTVSR", - "MTVSRD", - "MTVSRWA", - "MTVSRWZ", - "XXLAND", - "XXLANDQ", - "XXLANDC", - "XXLEQV", - "XXLNAND", - "XXLOR", - "XXLORC", - "XXLNOR", - "XXLORQ", - "XXLXOR", - "XXSEL", - "XXMRG", - "XXMRGHW", - "XXMRGLW", - "XXSPLT", - "XXSPLTW", - "XXPERM", - "XXPERMDI", - "XXSI", - "XXSLDWI", - "XSCV", - "XSCVDPSP", - "XSCVSPDP", - "XSCVDPSPN", - "XSCVSPDPN", - "XVCV", - "XVCVDPSP", - "XVCVSPDP", - "XSCVX", - "XSCVDPSXDS", - "XSCVDPSXWS", - "XSCVDPUXDS", - "XSCVDPUXWS", - "XSCVXP", - "XSCVSXDDP", - "XSCVUXDDP", - "XSCVSXDSP", - "XSCVUXDSP", - "XVCVX", - "XVCVDPSXDS", - "XVCVDPSXWS", - "XVCVDPUXDS", - "XVCVDPUXWS", - "XVCVSPSXDS", - "XVCVSPSXWS", - "XVCVSPUXDS", - "XVCVSPUXWS", - "XVCVXP", - "XVCVSXDDP", - "XVCVSXWDP", - "XVCVUXDDP", - "XVCVUXWDP", - "XVCVSXDSP", - "XVCVSXWSP", - "XVCVUXDSP", - "XVCVUXWSP", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/ppc64/anames9.go b/vendor/github.com/google/gops/internal/obj/ppc64/anames9.go deleted file mode 100644 index 6ec7b7b5..00000000 --- a/vendor/github.com/google/gops/internal/obj/ppc64/anames9.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 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 ppc64 - -var cnames9 = []string{ - "NONE", - "REG", - "FREG", - "VREG", - "VSREG", - "CREG", - "SPR", - "ZCON", - "SCON", - "UCON", - "ADDCON", - "ANDCON", - "LCON", - "DCON", - "SACON", - "SECON", - "LACON", - "LECON", - "DACON", - "SBRA", - "LBRA", - "SAUTO", - "LAUTO", - "SEXT", - "LEXT", - "ZOREG", - "SOREG", - "LOREG", - "FPSCR", - "MSR", - "XER", - "LR", - "CTR", - "ANY", - "GOK", - "ADDR", - "GOTADDR", - "TLS_LE", - "TLS_IE", - "TEXTSIZE", - "NCLASS", -} diff --git a/vendor/github.com/google/gops/internal/obj/ppc64/asm9.go b/vendor/github.com/google/gops/internal/obj/ppc64/asm9.go deleted file mode 100644 index 31bdeb68..00000000 --- a/vendor/github.com/google/gops/internal/obj/ppc64/asm9.go +++ /dev/null @@ -1,4552 +0,0 @@ -// cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package ppc64 - -import ( - "encoding/binary" - "fmt" - "log" - "sort" - - "github.com/google/gops/internal/obj" -) - -// Instruction layout. - -const ( - funcAlign = 8 -) - -const ( - r0iszero = 1 -) - -type Optab struct { - as obj.As // Opcode - a1 uint8 - a2 uint8 - a3 uint8 - a4 uint8 - type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r - size int8 - param int16 -} - -var optab = []Optab{ - {obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0}, - {obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0}, - {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0}, - {obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0}, - /* move register */ - {AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0}, - {AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0}, - {AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, - {AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, - {AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, - {AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, - {AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0}, - {AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0}, - {AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, - {AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, - {AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, - {AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, - {AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, - {AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, - {AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, - {AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, - {AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */ - {AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, - {AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0}, - {AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0}, - {AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0}, - {AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0}, - {AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0}, - {AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0}, - {AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, - {AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, - {AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, - {AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, - {AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0}, - {AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0}, - {AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0}, - {AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0}, - {ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, - {ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0}, - {ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0}, - {ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0}, - {AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */ - {AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0}, - {AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0}, - {AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0}, - {AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0}, - {AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0}, - {AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0}, - {ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */ - {ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0}, - {ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */ - {ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0}, - {ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, - {ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, - {ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0}, - {ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0}, - {ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0}, - {ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0}, - {ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, - {ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0}, - {ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0}, - {ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, - {ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, - {ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0}, - {ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0}, - {ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0}, - {ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0}, - {ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0}, - {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0}, - {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0}, - {ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0}, - {ARLDICL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0}, - {ARLDICL, C_SCON, C_REG, C_LCON, C_REG, 14, 4, 0}, - {ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0}, - {AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0}, - {AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 4, 0}, - {AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0}, - {AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0}, - {AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 4, 0}, - {AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0}, - {AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 4, 0}, - - /* store, short offset */ - {AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO}, - {AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, - {AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - - /* load, short offset */ - {AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO}, - {AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO}, - {AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB}, - {AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB}, - {AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP}, - {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP}, - {AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO}, - {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO}, - {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO}, - - /* store, long offset */ - {AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, - {AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, - {AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, - {AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, - {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, - {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, - {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, - {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, - {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, - {AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, - {AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, - {AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, - - /* load, long offset */ - {AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, - {AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, - {AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, - {AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB}, - {AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB}, - {AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, - {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, - {AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, - {AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP}, - {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP}, - {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, - {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, - {AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, - {AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO}, - {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO}, - {AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, - {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, - {AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, - {AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0}, - {AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0}, - - {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0}, - {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0}, - - {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0}, - - /* load constant */ - {AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, - {AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP}, - {AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB}, - {AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP}, - {AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */ - {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP}, - {AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB}, - {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP}, - {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */ - {AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP}, - {AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB}, - {AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP}, - {AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, - - /* load unsigned/long constants (TO DO: check) */ - {AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0}, - {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0}, - {AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO}, - {AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0}, - {AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0}, - {AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, - {AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0}, - {AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, - {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0}, - {ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0}, - {ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0}, - {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0}, - {ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0}, - {ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, - {ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0}, - {ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0}, - {ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0}, - {ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0}, - {ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0}, - {ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0}, - {ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0}, - {ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0}, - {ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0}, - {ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0}, - {ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0}, - {ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0}, - {AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB}, - {AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP}, - {AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO}, - {AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB}, - {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP}, - {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO}, - {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO}, - {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0}, - {AFMOVSX, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0}, - {AFMOVSX, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0}, - {AFMOVSX, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0}, - {AFMOVSX, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, - {AFMOVSZ, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0}, - {AFMOVSZ, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0}, - {ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0}, - {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0}, - {ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0}, - {ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0}, - {AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0}, - {AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0}, - {AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0}, - {AISEL, C_LCON, C_REG, C_REG, C_REG, 84, 4, 0}, - {AISEL, C_ZCON, C_REG, C_REG, C_REG, 84, 4, 0}, - {ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0}, - {ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0}, - {AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0}, - {AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0}, - {AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0}, - {AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0}, - {AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0}, - {AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0}, - {AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0}, - {AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0}, - {AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0}, - {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0}, - {AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0}, - {AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0}, - {AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0}, - {AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */ - {AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */ - {AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */ - - /* Vector instructions */ - - /* Vector load */ - {ALV, C_SOREG, C_NONE, C_NONE, C_VREG, 45, 4, 0}, /* vector load, x-form */ - - /* Vector store */ - {ASTV, C_VREG, C_NONE, C_NONE, C_SOREG, 44, 4, 0}, /* vector store, x-form */ - - /* Vector logical */ - {AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector and, vx-form */ - {AVOR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector or, vx-form */ - - /* Vector add */ - {AVADDUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned modulo, vx-form */ - {AVADDCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add & write carry unsigned, vx-form */ - {AVADDUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned saturate, vx-form */ - {AVADDSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add signed saturate, vx-form */ - {AVADDE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector add extended, va-form */ - - /* Vector subtract */ - {AVSUBUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned modulo, vx-form */ - {AVSUBCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract & write carry unsigned, vx-form */ - {AVSUBUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned saturate, vx-form */ - {AVSUBSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract signed saturate, vx-form */ - {AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector subtract extended, va-form */ - - /* Vector rotate */ - {AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */ - - /* Vector shift */ - {AVS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift, vx-form */ - {AVSA, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift algebraic, vx-form */ - {AVSOI, C_ANDCON, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector shift by octet immediate, va-form */ - - /* Vector count */ - {AVCLZ, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector count leading zeros, vx-form */ - {AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */ - - /* Vector compare */ - {AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare equal, vc-form */ - {AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare greater than, vc-form */ - - /* Vector permute */ - {AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */ - - /* Vector select */ - {AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */ - - /* Vector splat */ - {AVSPLT, C_SCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector splat, vx-form */ - {AVSPLT, C_ADDCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, - {AVSPLTI, C_SCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector splat immediate, vx-form */ - {AVSPLTI, C_ADDCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, - - /* Vector AES */ - {AVCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES cipher, vx-form */ - {AVNCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES inverse cipher, vx-form */ - {AVSBOX, C_VREG, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector AES subbytes, vx-form */ - - /* Vector SHA */ - {AVSHASIGMA, C_ANDCON, C_VREG, C_ANDCON, C_VREG, 82, 4, 0}, /* vector SHA sigma, vx-form */ - - /* VSX vector load */ - {ALXV, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx vector load, xx1-form */ - - /* VSX vector store */ - {ASTXV, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx vector store, xx1-form */ - - /* VSX scalar load */ - {ALXS, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar load, xx1-form */ - - /* VSX scalar store */ - {ASTXS, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar store, xx1-form */ - - /* VSX scalar as integer load */ - {ALXSI, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar as integer load, xx1-form */ - - /* VSX scalar store as integer */ - {ASTXSI, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar as integer store, xx1-form */ - - /* VSX move from VSR */ - {AMFVSR, C_VSREG, C_NONE, C_NONE, C_REG, 88, 4, 0}, /* vsx move from vsr, xx1-form */ - - /* VSX move to VSR */ - {AMTVSR, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */ - - /* VSX logical */ - {AXXLAND, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx and, xx3-form */ - {AXXLOR, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx or, xx3-form */ - - /* VSX select */ - {AXXSEL, C_VSREG, C_VSREG, C_VSREG, C_VSREG, 91, 4, 0}, /* vsx select, xx4-form */ - - /* VSX merge */ - {AXXMRG, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx merge, xx3-form */ - - /* VSX splat */ - {AXXSPLT, C_VSREG, C_NONE, C_SCON, C_VSREG, 89, 4, 0}, /* vsx splat, xx2-form */ - - /* VSX permute */ - {AXXPERM, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx permute, xx3-form */ - - /* VSX shift */ - {AXXSI, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx shift immediate, xx3-form */ - - /* VSX scalar FP-FP conversion */ - {AXSCV, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-fp conversion, xx2-form */ - - /* VSX vector FP-FP conversion */ - {AXVCV, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-fp conversion, xx2-form */ - - /* VSX scalar FP-integer conversion */ - {AXSCVX, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-integer conversion, xx2-form */ - - /* VSX scalar integer-FP conversion */ - {AXSCVXP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar integer-fp conversion, xx2-form */ - - /* VSX vector FP-integer conversion */ - {AXVCVX, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-integer conversion, xx2-form */ - - /* VSX vector integer-FP conversion */ - {AXVCVXP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector integer-fp conversion, xx2-form */ - - /* 64-bit special registers */ - {AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0}, - {AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0}, - {AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0}, - {AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0}, - {AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0}, - - /* 32-bit special registers (gloss over sign-extension or not?) */ - {AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0}, - {AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0}, - {AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0}, - {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0}, - {AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0}, - {AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0}, - {AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0}, - {AMOVFL, C_REG, C_NONE, C_LCON, C_CREG, 69, 4, 0}, - {AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0}, - {AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0}, - {ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0}, - {ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0}, - {ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0}, - {ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0}, - {ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0}, - {ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0}, - {ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0}, - {ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0}, - {AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0}, - {AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0}, - {ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0}, - {ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0}, - {ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0}, - {ADCBF, C_ZOREG, C_REG, C_NONE, C_NONE, 43, 4, 0}, - {AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0}, - {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0}, - {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, - {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, - {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0}, - {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0}, - {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0}, - {ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0}, - {ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0}, - {ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0}, - {ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0}, - {ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, - {ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0}, - {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0}, - {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0}, - {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0}, - {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0}, - {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0}, - {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL - {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL - - {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0}, -} - -var oprange [ALAST & obj.AMask][]Optab - -var xcmp [C_NCLASS][C_NCLASS]bool - -func span9(ctxt *obj.Link, cursym *obj.LSym) { - p := cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - ctxt.Cursym = cursym - ctxt.Autosize = int32(p.To.Offset) - - if oprange[AANDN&obj.AMask] == nil { - buildop(ctxt) - } - - c := int64(0) - p.Pc = c - - var m int - var o *Optab - for p = p.Link; p != nil; p = p.Link { - ctxt.Curp = p - p.Pc = c - o = oplook(ctxt, p) - m = int(o.size) - if m == 0 { - if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { - ctxt.Diag("zero-width instruction\n%v", p) - } - continue - } - - c += int64(m) - } - - cursym.Size = c - - /* - * if any procedure is large enough to - * generate a large SBRA branch, then - * generate extra passes putting branches - * around jmps to fix. this is rare. - */ - bflag := 1 - - var otxt int64 - var q *obj.Prog - for bflag != 0 { - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f span1\n", obj.Cputime()) - } - bflag = 0 - c = 0 - for p = cursym.Text.Link; p != nil; p = p.Link { - p.Pc = c - o = oplook(ctxt, p) - - // very large conditional branches - if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil { - otxt = p.Pcond.Pc - c - if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 { - q = ctxt.NewProg() - q.Link = p.Link - p.Link = q - q.As = ABR - q.To.Type = obj.TYPE_BRANCH - q.Pcond = p.Pcond - p.Pcond = q - q = ctxt.NewProg() - q.Link = p.Link - p.Link = q - q.As = ABR - q.To.Type = obj.TYPE_BRANCH - q.Pcond = q.Link.Link - - //addnop(p->link); - //addnop(p); - bflag = 1 - } - } - - m = int(o.size) - if m == 0 { - if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD { - ctxt.Diag("zero-width instruction\n%v", p) - } - continue - } - - c += int64(m) - } - - cursym.Size = c - } - - c += -c & (funcAlign - 1) - cursym.Size = c - - /* - * lay out the code, emitting code and data relocations. - */ - - cursym.Grow(cursym.Size) - - bp := cursym.P - var i int32 - var out [6]uint32 - for p := cursym.Text.Link; p != nil; p = p.Link { - ctxt.Pc = p.Pc - ctxt.Curp = p - o = oplook(ctxt, p) - if int(o.size) > 4*len(out) { - log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p) - } - asmout(ctxt, p, o, out[:]) - for i = 0; i < int32(o.size/4); i++ { - ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) - bp = bp[4:] - } - } -} - -func isint32(v int64) bool { - return int64(int32(v)) == v -} - -func isuint32(v uint64) bool { - return uint64(uint32(v)) == v -} - -func aclass(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return C_NONE - - case obj.TYPE_REG: - if REG_R0 <= a.Reg && a.Reg <= REG_R31 { - return C_REG - } - if REG_F0 <= a.Reg && a.Reg <= REG_F31 { - return C_FREG - } - if REG_V0 <= a.Reg && a.Reg <= REG_V31 { - return C_VREG - } - if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 { - return C_VSREG - } - if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR { - return C_CREG - } - if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 { - switch a.Reg { - case REG_LR: - return C_LR - - case REG_XER: - return C_XER - - case REG_CTR: - return C_CTR - } - - return C_SPR - } - - if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 { - return C_SPR - } - if a.Reg == REG_FPSCR { - return C_FPSCR - } - if a.Reg == REG_MSR { - return C_MSR - } - return C_GOK - - case obj.TYPE_MEM: - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_STATIC: - if a.Sym == nil { - break - } - ctxt.Instoffset = a.Offset - if a.Sym != nil { // use relocation - if a.Sym.Type == obj.STLSBSS { - if ctxt.Flag_shared { - return C_TLS_IE - } else { - return C_TLS_LE - } - } - return C_ADDR - } - return C_LEXT - - case obj.NAME_GOTREF: - return C_GOTADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SAUTO - } - return C_LAUTO - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize() - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SAUTO - } - return C_LAUTO - - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if ctxt.Instoffset == 0 { - return C_ZOREG - } - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SOREG - } - return C_LOREG - } - - return C_GOK - - case obj.TYPE_TEXTSIZE: - return C_TEXTSIZE - - case obj.TYPE_CONST, - obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if a.Reg != 0 { - if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { - return C_SACON - } - if isint32(ctxt.Instoffset) { - return C_LACON - } - return C_DACON - } - - goto consize - - case obj.NAME_EXTERN, - obj.NAME_STATIC: - s := a.Sym - if s == nil { - break - } - if s.Type == obj.SCONST { - ctxt.Instoffset = a.Offset - goto consize - } - - ctxt.Instoffset = a.Offset - - /* not sure why this barfs */ - return C_LCON - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SACON - } - return C_LACON - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize() - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SACON - } - return C_LACON - } - - return C_GOK - - consize: - if ctxt.Instoffset >= 0 { - if ctxt.Instoffset == 0 { - return C_ZCON - } - if ctxt.Instoffset <= 0x7fff { - return C_SCON - } - if ctxt.Instoffset <= 0xffff { - return C_ANDCON - } - if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */ - return C_UCON - } - if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) { - return C_LCON - } - return C_DCON - } - - if ctxt.Instoffset >= -0x8000 { - return C_ADDCON - } - if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) { - return C_UCON - } - if isint32(ctxt.Instoffset) { - return C_LCON - } - return C_DCON - - case obj.TYPE_BRANCH: - if a.Sym != nil && ctxt.Flag_dynlink { - return C_LBRAPIC - } - return C_SBRA - } - - return C_GOK -} - -func prasm(p *obj.Prog) { - fmt.Printf("%v\n", p) -} - -func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { - a1 := int(p.Optab) - if a1 != 0 { - return &optab[a1-1] - } - a1 = int(p.From.Class) - if a1 == 0 { - a1 = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(a1) - } - - a1-- - a3 := C_NONE + 1 - if p.From3 != nil { - a3 = int(p.From3.Class) - if a3 == 0 { - a3 = aclass(ctxt, p.From3) + 1 - p.From3.Class = int8(a3) - } - } - - a3-- - a4 := int(p.To.Class) - if a4 == 0 { - a4 = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(a4) - } - - a4-- - a2 := C_NONE - if p.Reg != 0 { - if REG_R0 <= p.Reg && p.Reg <= REG_R31 { - a2 = C_REG - } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 { - a2 = C_VREG - } else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 { - a2 = C_VSREG - } else if REG_F0 <= p.Reg && p.Reg <= REG_F31 { - a2 = C_FREG - } - } - - //print("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4); - ops := oprange[p.As&obj.AMask] - c1 := &xcmp[a1] - c3 := &xcmp[a3] - c4 := &xcmp[a4] - for i := range ops { - op := &ops[i] - if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] { - p.Optab = uint16(cap(optab) - cap(ops) + i + 1) - return op - } - } - - ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4)) - prasm(p) - if ops == nil { - ops = optab - } - return &ops[0] -} - -func cmp(a int, b int) bool { - if a == b { - return true - } - switch a { - case C_LCON: - if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON { - return true - } - - case C_ADDCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_ANDCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_SPR: - if b == C_LR || b == C_XER || b == C_CTR { - return true - } - - case C_UCON: - if b == C_ZCON { - return true - } - - case C_SCON: - if b == C_ZCON { - return true - } - - case C_LACON: - if b == C_SACON { - return true - } - - case C_LBRA: - if b == C_SBRA { - return true - } - - case C_LEXT: - if b == C_SEXT { - return true - } - - case C_LAUTO: - if b == C_SAUTO { - return true - } - - case C_REG: - if b == C_ZCON { - return r0iszero != 0 /*TypeKind(100016)*/ - } - - case C_LOREG: - if b == C_ZOREG || b == C_SOREG { - return true - } - - case C_SOREG: - if b == C_ZOREG { - return true - } - - case C_ANY: - return true - } - - return false -} - -type ocmp []Optab - -func (x ocmp) Len() int { - return len(x) -} - -func (x ocmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x ocmp) Less(i, j int) bool { - p1 := &x[i] - p2 := &x[j] - n := int(p1.as) - int(p2.as) - if n != 0 { - return n < 0 - } - n = int(p1.a1) - int(p2.a1) - if n != 0 { - return n < 0 - } - n = int(p1.a2) - int(p2.a2) - if n != 0 { - return n < 0 - } - n = int(p1.a3) - int(p2.a3) - if n != 0 { - return n < 0 - } - n = int(p1.a4) - int(p2.a4) - if n != 0 { - return n < 0 - } - return false -} -func opset(a, b0 obj.As) { - oprange[a&obj.AMask] = oprange[b0] -} - -func buildop(ctxt *obj.Link) { - var n int - - for i := 0; i < C_NCLASS; i++ { - for n = 0; n < C_NCLASS; n++ { - if cmp(n, i) { - xcmp[i][n] = true - } - } - } - for n = 0; optab[n].as != obj.AXXX; n++ { - } - sort.Sort(ocmp(optab[:n])) - for i := 0; i < n; i++ { - r := optab[i].as - r0 := r & obj.AMask - start := i - for optab[i].as == r { - i++ - } - oprange[r0] = optab[start:i] - i-- - - switch r { - default: - ctxt.Diag("unknown op in build: %v", r) - log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r) - - case ADCBF: /* unary indexed: op (b+a); op (b) */ - opset(ADCBI, r0) - - opset(ADCBST, r0) - opset(ADCBT, r0) - opset(ADCBTST, r0) - opset(ADCBZ, r0) - opset(AICBI, r0) - - case AECOWX: /* indexed store: op s,(b+a); op s,(b) */ - opset(ASTWCCC, r0) - opset(ASTBCCC, r0) - - opset(ASTDCCC, r0) - - case AREM: /* macro */ - opset(AREMCC, r0) - - opset(AREMV, r0) - opset(AREMVCC, r0) - - case AREMU: - opset(AREMU, r0) - opset(AREMUCC, r0) - opset(AREMUV, r0) - opset(AREMUVCC, r0) - - case AREMD: - opset(AREMDCC, r0) - opset(AREMDV, r0) - opset(AREMDVCC, r0) - - case AREMDU: - opset(AREMDU, r0) - opset(AREMDUCC, r0) - opset(AREMDUV, r0) - opset(AREMDUVCC, r0) - - case ADIVW: /* op Rb[,Ra],Rd */ - opset(AMULHW, r0) - - opset(AMULHWCC, r0) - opset(AMULHWU, r0) - opset(AMULHWUCC, r0) - opset(AMULLWCC, r0) - opset(AMULLWVCC, r0) - opset(AMULLWV, r0) - opset(ADIVWCC, r0) - opset(ADIVWV, r0) - opset(ADIVWVCC, r0) - opset(ADIVWU, r0) - opset(ADIVWUCC, r0) - opset(ADIVWUV, r0) - opset(ADIVWUVCC, r0) - opset(AADDCC, r0) - opset(AADDCV, r0) - opset(AADDCVCC, r0) - opset(AADDV, r0) - opset(AADDVCC, r0) - opset(AADDE, r0) - opset(AADDECC, r0) - opset(AADDEV, r0) - opset(AADDEVCC, r0) - opset(ACRAND, r0) - opset(ACRANDN, r0) - opset(ACREQV, r0) - opset(ACRNAND, r0) - opset(ACRNOR, r0) - opset(ACROR, r0) - opset(ACRORN, r0) - opset(ACRXOR, r0) - opset(AMULHD, r0) - opset(AMULHDCC, r0) - opset(AMULHDU, r0) - opset(AMULHDUCC, r0) - opset(AMULLD, r0) - opset(AMULLDCC, r0) - opset(AMULLDVCC, r0) - opset(AMULLDV, r0) - opset(ADIVD, r0) - opset(ADIVDCC, r0) - opset(ADIVDE, r0) - opset(ADIVDEU, r0) - opset(ADIVDECC, r0) - opset(ADIVDEUCC, r0) - opset(ADIVDVCC, r0) - opset(ADIVDV, r0) - opset(ADIVDU, r0) - opset(ADIVDUCC, r0) - opset(ADIVDUVCC, r0) - opset(ADIVDUCC, r0) - - case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */ - opset(AMOVH, r0) - - opset(AMOVHZ, r0) - - case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */ - opset(AMOVHU, r0) - - opset(AMOVHZU, r0) - opset(AMOVWU, r0) - opset(AMOVWZU, r0) - opset(AMOVDU, r0) - opset(AMOVMW, r0) - - case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */ - opset(ALVEBX, r0) - opset(ALVEHX, r0) - opset(ALVEWX, r0) - opset(ALVX, r0) - opset(ALVXL, r0) - opset(ALVSL, r0) - opset(ALVSR, r0) - - case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */ - opset(ASTVEBX, r0) - opset(ASTVEHX, r0) - opset(ASTVEWX, r0) - opset(ASTVX, r0) - opset(ASTVXL, r0) - - case AVAND: /* vand, vandc, vnand */ - opset(AVANDL, r0) - opset(AVANDC, r0) - opset(AVNAND, r0) - - case AVOR: /* vor, vorc, vxor, vnor, veqv */ - opset(AVORL, r0) - opset(AVORC, r0) - opset(AVXOR, r0) - opset(AVNOR, r0) - opset(AVEQV, r0) - - case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */ - opset(AVADDUBM, r0) - opset(AVADDUHM, r0) - opset(AVADDUWM, r0) - opset(AVADDUDM, r0) - opset(AVADDUQM, r0) - - case AVADDCU: /* vaddcuq, vaddcuw */ - opset(AVADDCUQ, r0) - opset(AVADDCUW, r0) - - case AVADDUS: /* vaddubs, vadduhs, vadduws */ - opset(AVADDUBS, r0) - opset(AVADDUHS, r0) - opset(AVADDUWS, r0) - - case AVADDSS: /* vaddsbs, vaddshs, vaddsws */ - opset(AVADDSBS, r0) - opset(AVADDSHS, r0) - opset(AVADDSWS, r0) - - case AVADDE: /* vaddeuqm, vaddecuq */ - opset(AVADDEUQM, r0) - opset(AVADDECUQ, r0) - - case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */ - opset(AVSUBUBM, r0) - opset(AVSUBUHM, r0) - opset(AVSUBUWM, r0) - opset(AVSUBUDM, r0) - opset(AVSUBUQM, r0) - - case AVSUBCU: /* vsubcuq, vsubcuw */ - opset(AVSUBCUQ, r0) - opset(AVSUBCUW, r0) - - case AVSUBUS: /* vsububs, vsubuhs, vsubuws */ - opset(AVSUBUBS, r0) - opset(AVSUBUHS, r0) - opset(AVSUBUWS, r0) - - case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */ - opset(AVSUBSBS, r0) - opset(AVSUBSHS, r0) - opset(AVSUBSWS, r0) - - case AVSUBE: /* vsubeuqm, vsubecuq */ - opset(AVSUBEUQM, r0) - opset(AVSUBECUQ, r0) - - case AVR: /* vrlb, vrlh, vrlw, vrld */ - opset(AVRLB, r0) - opset(AVRLH, r0) - opset(AVRLW, r0) - opset(AVRLD, r0) - - case AVS: /* vs[l,r], vs[l,r]o, vs[l,r]b, vs[l,r]h, vs[l,r]w, vs[l,r]d */ - opset(AVSLB, r0) - opset(AVSLH, r0) - opset(AVSLW, r0) - opset(AVSL, r0) - opset(AVSLO, r0) - opset(AVSRB, r0) - opset(AVSRH, r0) - opset(AVSRW, r0) - opset(AVSR, r0) - opset(AVSRO, r0) - opset(AVSLD, r0) - opset(AVSRD, r0) - - case AVSA: /* vsrab, vsrah, vsraw, vsrad */ - opset(AVSRAB, r0) - opset(AVSRAH, r0) - opset(AVSRAW, r0) - opset(AVSRAD, r0) - - case AVSOI: /* vsldoi */ - opset(AVSLDOI, r0) - - case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */ - opset(AVCLZB, r0) - opset(AVCLZH, r0) - opset(AVCLZW, r0) - opset(AVCLZD, r0) - - case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */ - opset(AVPOPCNTB, r0) - opset(AVPOPCNTH, r0) - opset(AVPOPCNTW, r0) - opset(AVPOPCNTD, r0) - - case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */ - opset(AVCMPEQUB, r0) - opset(AVCMPEQUBCC, r0) - opset(AVCMPEQUH, r0) - opset(AVCMPEQUHCC, r0) - opset(AVCMPEQUW, r0) - opset(AVCMPEQUWCC, r0) - opset(AVCMPEQUD, r0) - opset(AVCMPEQUDCC, r0) - - case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */ - opset(AVCMPGTUB, r0) - opset(AVCMPGTUBCC, r0) - opset(AVCMPGTUH, r0) - opset(AVCMPGTUHCC, r0) - opset(AVCMPGTUW, r0) - opset(AVCMPGTUWCC, r0) - opset(AVCMPGTUD, r0) - opset(AVCMPGTUDCC, r0) - opset(AVCMPGTSB, r0) - opset(AVCMPGTSBCC, r0) - opset(AVCMPGTSH, r0) - opset(AVCMPGTSHCC, r0) - opset(AVCMPGTSW, r0) - opset(AVCMPGTSWCC, r0) - opset(AVCMPGTSD, r0) - opset(AVCMPGTSDCC, r0) - - case AVPERM: /* vperm */ - opset(AVPERM, r0) - - case AVSEL: /* vsel */ - opset(AVSEL, r0) - - case AVSPLT: /* vspltb, vsplth, vspltw */ - opset(AVSPLTB, r0) - opset(AVSPLTH, r0) - opset(AVSPLTW, r0) - - case AVSPLTI: /* vspltisb, vspltish, vspltisw */ - opset(AVSPLTISB, r0) - opset(AVSPLTISH, r0) - opset(AVSPLTISW, r0) - - case AVCIPH: /* vcipher, vcipherlast */ - opset(AVCIPHER, r0) - opset(AVCIPHERLAST, r0) - - case AVNCIPH: /* vncipher, vncipherlast */ - opset(AVNCIPHER, r0) - opset(AVNCIPHERLAST, r0) - - case AVSBOX: /* vsbox */ - opset(AVSBOX, r0) - - case AVSHASIGMA: /* vshasigmaw, vshasigmad */ - opset(AVSHASIGMAW, r0) - opset(AVSHASIGMAD, r0) - - case ALXV: /* lxvd2x, lxvdsx, lxvw4x */ - opset(ALXVD2X, r0) - opset(ALXVDSX, r0) - opset(ALXVW4X, r0) - - case ASTXV: /* stxvd2x, stxvdsx, stxvw4x */ - opset(ASTXVD2X, r0) - opset(ASTXVW4X, r0) - - case ALXS: /* lxsdx */ - opset(ALXSDX, r0) - - case ASTXS: /* stxsdx */ - opset(ASTXSDX, r0) - - case ALXSI: /* lxsiwax, lxsiwzx */ - opset(ALXSIWAX, r0) - opset(ALXSIWZX, r0) - - case ASTXSI: /* stxsiwx */ - opset(ASTXSIWX, r0) - - case AMFVSR: /* mfvsrd, mfvsrwz */ - opset(AMFVSRD, r0) - opset(AMFVSRWZ, r0) - - case AMTVSR: /* mtvsrd, mtvsrwa, mtvsrwz */ - opset(AMTVSRD, r0) - opset(AMTVSRWA, r0) - opset(AMTVSRWZ, r0) - - case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */ - opset(AXXLANDQ, r0) - opset(AXXLANDC, r0) - opset(AXXLEQV, r0) - opset(AXXLNAND, r0) - - case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */ - opset(AXXLORC, r0) - opset(AXXLNOR, r0) - opset(AXXLORQ, r0) - opset(AXXLXOR, r0) - - case AXXSEL: /* xxsel */ - opset(AXXSEL, r0) - - case AXXMRG: /* xxmrghw, xxmrglw */ - opset(AXXMRGHW, r0) - opset(AXXMRGLW, r0) - - case AXXSPLT: /* xxspltw */ - opset(AXXSPLTW, r0) - - case AXXPERM: /* xxpermdi */ - opset(AXXPERMDI, r0) - - case AXXSI: /* xxsldwi */ - opset(AXXSLDWI, r0) - - case AXSCV: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */ - opset(AXSCVDPSP, r0) - opset(AXSCVSPDP, r0) - opset(AXSCVDPSPN, r0) - opset(AXSCVSPDPN, r0) - - case AXVCV: /* xvcvdpsp, xvcvspdp */ - opset(AXVCVDPSP, r0) - opset(AXVCVSPDP, r0) - - case AXSCVX: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */ - opset(AXSCVDPSXDS, r0) - opset(AXSCVDPSXWS, r0) - opset(AXSCVDPUXDS, r0) - opset(AXSCVDPUXWS, r0) - - case AXSCVXP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */ - opset(AXSCVSXDDP, r0) - opset(AXSCVUXDDP, r0) - opset(AXSCVSXDSP, r0) - opset(AXSCVUXDSP, r0) - - case AXVCVX: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */ - opset(AXVCVDPSXDS, r0) - opset(AXVCVDPSXWS, r0) - opset(AXVCVDPUXDS, r0) - opset(AXVCVDPUXWS, r0) - opset(AXVCVSPSXDS, r0) - opset(AXVCVSPSXWS, r0) - opset(AXVCVSPUXDS, r0) - opset(AXVCVSPUXWS, r0) - - case AXVCVXP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */ - opset(AXVCVSXDDP, r0) - opset(AXVCVSXWDP, r0) - opset(AXVCVUXDDP, r0) - opset(AXVCVUXWDP, r0) - opset(AXVCVSXDSP, r0) - opset(AXVCVSXWSP, r0) - opset(AXVCVUXDSP, r0) - opset(AXVCVUXWSP, r0) - - case AAND: /* logical op Rb,Rs,Ra; no literal */ - opset(AANDN, r0) - - opset(AANDNCC, r0) - opset(AEQV, r0) - opset(AEQVCC, r0) - opset(ANAND, r0) - opset(ANANDCC, r0) - opset(ANOR, r0) - opset(ANORCC, r0) - opset(AORCC, r0) - opset(AORN, r0) - opset(AORNCC, r0) - opset(AXORCC, r0) - - case AADDME: /* op Ra, Rd */ - opset(AADDMECC, r0) - - opset(AADDMEV, r0) - opset(AADDMEVCC, r0) - opset(AADDZE, r0) - opset(AADDZECC, r0) - opset(AADDZEV, r0) - opset(AADDZEVCC, r0) - opset(ASUBME, r0) - opset(ASUBMECC, r0) - opset(ASUBMEV, r0) - opset(ASUBMEVCC, r0) - opset(ASUBZE, r0) - opset(ASUBZECC, r0) - opset(ASUBZEV, r0) - opset(ASUBZEVCC, r0) - - case AADDC: - opset(AADDCCC, r0) - - case ABEQ: - opset(ABGE, r0) - opset(ABGT, r0) - opset(ABLE, r0) - opset(ABLT, r0) - opset(ABNE, r0) - opset(ABVC, r0) - opset(ABVS, r0) - - case ABR: - opset(ABL, r0) - - case ABC: - opset(ABCL, r0) - - case AEXTSB: /* op Rs, Ra */ - opset(AEXTSBCC, r0) - - opset(AEXTSH, r0) - opset(AEXTSHCC, r0) - opset(ACNTLZW, r0) - opset(ACNTLZWCC, r0) - opset(ACNTLZD, r0) - opset(AEXTSW, r0) - opset(AEXTSWCC, r0) - opset(ACNTLZDCC, r0) - - case AFABS: /* fop [s,]d */ - opset(AFABSCC, r0) - - opset(AFNABS, r0) - opset(AFNABSCC, r0) - opset(AFNEG, r0) - opset(AFNEGCC, r0) - opset(AFRSP, r0) - opset(AFRSPCC, r0) - opset(AFCTIW, r0) - opset(AFCTIWCC, r0) - opset(AFCTIWZ, r0) - opset(AFCTIWZCC, r0) - opset(AFCTID, r0) - opset(AFCTIDCC, r0) - opset(AFCTIDZ, r0) - opset(AFCTIDZCC, r0) - opset(AFCFID, r0) - opset(AFCFIDCC, r0) - opset(AFCFIDU, r0) - opset(AFCFIDUCC, r0) - opset(AFRES, r0) - opset(AFRESCC, r0) - opset(AFRIM, r0) - opset(AFRIMCC, r0) - opset(AFRIP, r0) - opset(AFRIPCC, r0) - opset(AFRIZ, r0) - opset(AFRIZCC, r0) - opset(AFRSQRTE, r0) - opset(AFRSQRTECC, r0) - opset(AFSQRT, r0) - opset(AFSQRTCC, r0) - opset(AFSQRTS, r0) - opset(AFSQRTSCC, r0) - - case AFADD: - opset(AFADDS, r0) - opset(AFADDCC, r0) - opset(AFADDSCC, r0) - opset(AFDIV, r0) - opset(AFDIVS, r0) - opset(AFDIVCC, r0) - opset(AFDIVSCC, r0) - opset(AFSUB, r0) - opset(AFSUBS, r0) - opset(AFSUBCC, r0) - opset(AFSUBSCC, r0) - - case AFMADD: - opset(AFMADDCC, r0) - opset(AFMADDS, r0) - opset(AFMADDSCC, r0) - opset(AFMSUB, r0) - opset(AFMSUBCC, r0) - opset(AFMSUBS, r0) - opset(AFMSUBSCC, r0) - opset(AFNMADD, r0) - opset(AFNMADDCC, r0) - opset(AFNMADDS, r0) - opset(AFNMADDSCC, r0) - opset(AFNMSUB, r0) - opset(AFNMSUBCC, r0) - opset(AFNMSUBS, r0) - opset(AFNMSUBSCC, r0) - opset(AFSEL, r0) - opset(AFSELCC, r0) - - case AFMUL: - opset(AFMULS, r0) - opset(AFMULCC, r0) - opset(AFMULSCC, r0) - - case AFCMPO: - opset(AFCMPU, r0) - - case AISEL: - opset(AISEL, r0) - - case AMTFSB0: - opset(AMTFSB0CC, r0) - opset(AMTFSB1, r0) - opset(AMTFSB1CC, r0) - - case ANEG: /* op [Ra,] Rd */ - opset(ANEGCC, r0) - - opset(ANEGV, r0) - opset(ANEGVCC, r0) - - case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */ - opset(AXOR, r0) - - case ASLW: - opset(ASLWCC, r0) - opset(ASRW, r0) - opset(ASRWCC, r0) - - case ASLD: - opset(ASLDCC, r0) - opset(ASRD, r0) - opset(ASRDCC, r0) - - case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ - opset(ASRAWCC, r0) - - case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ - opset(ASRADCC, r0) - - case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */ - opset(ASUB, r0) - - opset(ASUBCC, r0) - opset(ASUBV, r0) - opset(ASUBVCC, r0) - opset(ASUBCCC, r0) - opset(ASUBCV, r0) - opset(ASUBCVCC, r0) - opset(ASUBE, r0) - opset(ASUBECC, r0) - opset(ASUBEV, r0) - opset(ASUBEVCC, r0) - - case ASYNC: - opset(AISYNC, r0) - opset(ALWSYNC, r0) - opset(APTESYNC, r0) - opset(ATLBSYNC, r0) - - case ARLWMI: - opset(ARLWMICC, r0) - opset(ARLWNM, r0) - opset(ARLWNMCC, r0) - - case ARLDMI: - opset(ARLDMICC, r0) - opset(ARLDIMI, r0) - opset(ARLDIMICC, r0) - - case ARLDC: - opset(ARLDCCC, r0) - - case ARLDCL: - opset(ARLDCR, r0) - opset(ARLDCLCC, r0) - opset(ARLDCRCC, r0) - - case ARLDICL: - opset(ARLDICLCC, r0) - opset(ARLDICR, r0) - opset(ARLDICRCC, r0) - - case AFMOVD: - opset(AFMOVDCC, r0) - opset(AFMOVDU, r0) - opset(AFMOVS, r0) - opset(AFMOVSU, r0) - - case AECIWX: - opset(ALBAR, r0) - opset(ALWAR, r0) - opset(ALDAR, r0) - - case ASYSCALL: /* just the op; flow of control */ - opset(ARFI, r0) - - opset(ARFCI, r0) - opset(ARFID, r0) - opset(AHRFID, r0) - - case AMOVHBR: - opset(AMOVWBR, r0) - opset(AMOVDBR, r0) - - case ASLBMFEE: - opset(ASLBMFEV, r0) - - case ATW: - opset(ATD, r0) - - case ATLBIE: - opset(ASLBIE, r0) - opset(ATLBIEL, r0) - - case AEIEIO: - opset(ASLBIA, r0) - - case ACMP: - opset(ACMPW, r0) - - case ACMPU: - opset(ACMPWU, r0) - - case AADD, - AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */ - AFMOVSX, - AFMOVSZ, - ALSW, - AMOVW, - /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */ - AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */ - AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */ - AMOVB, /* macro: move byte with sign extension */ - AMOVBU, /* macro: move byte with sign extension & update */ - AMOVFL, - AMULLW, - /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */ - ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */ - ASTSW, - ASLBMTE, - AWORD, - ADWORD, - obj.ANOP, - obj.ATEXT, - obj.AUNDEF, - obj.AUSEFIELD, - obj.AFUNCDATA, - obj.APCDATA, - obj.ADUFFZERO, - obj.ADUFFCOPY: - break - } - } -} - -func OPVXX1(o uint32, xo uint32, oe uint32) uint32 { - return o<<26 | xo<<1 | oe<<11 -} - -func OPVXX2(o uint32, xo uint32, oe uint32) uint32 { - return o<<26 | xo<<2 | oe<<11 -} - -func OPVXX3(o uint32, xo uint32, oe uint32) uint32 { - return o<<26 | xo<<3 | oe<<11 -} - -func OPVXX4(o uint32, xo uint32, oe uint32) uint32 { - return o<<26 | xo<<4 | oe<<11 -} - -func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 { - return o<<26 | xo | oe<<11 | rc&1 -} - -func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 { - return o<<26 | xo | oe<<11 | (rc&1)<<10 -} - -func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 { - return o<<26 | xo<<1 | oe<<10 | rc&1 -} - -func OPCC(o uint32, xo uint32, rc uint32) uint32 { - return OPVCC(o, xo, 0, rc) -} - -func OP(o uint32, xo uint32) uint32 { - return OPVCC(o, xo, 0, 0) -} - -/* the order is dest, a/s, b/imm for both arithmetic and logical operations */ -func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 -} - -/* VX-form 2-register operands, r/r/none */ -func AOP_RR(op uint32, d uint32, a uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<11 -} - -/* VA-form 4-register operands */ -func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6 -} - -func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF -} - -/* VX-form 2-register + UIM operands */ -func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 { - return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11 -} - -/* VX-form 2-register + ST + SIX operands */ -func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11 -} - -/* VA-form 3-register + SHB operands */ -func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6 -} - -/* VX-form 1-register + SIM operands */ -func AOP_IR(op uint32, d uint32, simm uint32) uint32 { - return op | (d&31)<<21 | (simm&31)<<16 -} - -/* XX1-form 3-register operands, 1 VSR operand */ -func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 { - /* For the XX-form encodings, we need the VSX register number to be exactly */ - /* between 0-63, so we can properly set the rightmost bits. */ - r := d - REG_VS0 - return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5 -} - -/* XX2-form 3-register operands, 2 VSR operands */ -func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 { - xt := d - REG_VS0 - xb := b - REG_VS0 - return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5 -} - -/* XX3-form 3 VSR operands */ -func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 { - xt := d - REG_VS0 - xa := a - REG_VS0 - xb := b - REG_VS0 - return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5 -} - -/* XX3-form 3 VSR operands + immediate */ -func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 { - xt := d - REG_VS0 - xa := a - REG_VS0 - xb := b - REG_VS0 - return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5 -} - -/* XX4-form, 4 VSR operands */ -func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 { - xt := d - REG_VS0 - xa := a - REG_VS0 - xb := b - REG_VS0 - xc := c - REG_VS0 - return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xc&31)<<6 | (xc&32)>>2 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5 -} - -func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 { - return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11 -} - -func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 { - return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF -} - -func OP_BR(op uint32, li uint32, aa uint32) uint32 { - return op | li&0x03FFFFFC | aa<<1 -} - -func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 { - return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1 -} - -func OP_BCR(op uint32, bo uint32, bi uint32) uint32 { - return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 -} - -func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 { - return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1 -} - -func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 { - return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6 -} - -const ( - /* each rhs is OPVCC(_, _, _, _) */ - OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0 - OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0 - OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0 - OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0 - OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0 - OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0 - OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0 - OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0 - OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0 - OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0 - OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0 - OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0 - OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0 - OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0 - OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0 - OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0 - OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0 - OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0 - OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0 - OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0 - OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0 - OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0 - OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0 - OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0 - OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0 - OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0 - OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0 - OP_OR = 31<<26 | 444<<1 | 0<<10 | 0 - OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0 - OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0 - OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0 - OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0 - OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0 - OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0 - OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0 -) - -func oclass(a *obj.Addr) int { - return int(a.Class) - 1 -} - -const ( - D_FORM = iota - DS_FORM -) - -// opform returns the form (D_FORM or DS_FORM) of an instruction. Used to decide on -// which relocation to use with a load or store and only supports the needed -// instructions. -func opform(ctxt *obj.Link, insn uint32) int { - switch insn { - default: - ctxt.Diag("bad insn in loadform: %x", insn) - case OPVCC(58, 0, 0, 0), // ld - OPVCC(58, 0, 0, 0) | 1<<1, // lwa - OPVCC(62, 0, 0, 0): // std - return DS_FORM - case OP_ADDI, // add - OPVCC(32, 0, 0, 0), // lwz - OPVCC(42, 0, 0, 0), // lha - OPVCC(40, 0, 0, 0), // lhz - OPVCC(34, 0, 0, 0), // lbz - OPVCC(50, 0, 0, 0), // lfd - OPVCC(48, 0, 0, 0), // lfs - OPVCC(36, 0, 0, 0), // stw - OPVCC(44, 0, 0, 0), // sth - OPVCC(38, 0, 0, 0), // stb - OPVCC(54, 0, 0, 0), // stfd - OPVCC(52, 0, 0, 0): // stfs - return D_FORM - } - return 0 -} - -// Encode instructions and create relocation for accessing s+d according to the -// instruction op with source or destination (as appropriate) register reg. -func symbolAccess(ctxt *obj.Link, s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) { - var base uint32 - form := opform(ctxt, op) - if ctxt.Flag_shared { - base = REG_R2 - } else { - base = REG_R0 - } - o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0) - o2 = AOP_IRR(op, uint32(reg), REGTMP, 0) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = s - rel.Add = d - if ctxt.Flag_shared { - switch form { - case D_FORM: - rel.Type = obj.R_ADDRPOWER_TOCREL - case DS_FORM: - rel.Type = obj.R_ADDRPOWER_TOCREL_DS - } - - } else { - switch form { - case D_FORM: - rel.Type = obj.R_ADDRPOWER - case DS_FORM: - rel.Type = obj.R_ADDRPOWER_DS - } - } - return -} - -/* - * 32-bit masks - */ -func getmask(m []byte, v uint32) bool { - m[1] = 0 - m[0] = m[1] - if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */ - if getmask(m, ^v) { - i := int(m[0]) - m[0] = m[1] + 1 - m[1] = byte(i - 1) - return true - } - - return false - } - - for i := 0; i < 32; i++ { - if v&(1<= 32 || v&(1<= 64 || v&(uint64(1)<> 16) - if isuint32(uint64(d)) { - return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v)) - } - return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v)) -} - -func high16adjusted(d int32) uint16 { - if d&0x8000 != 0 { - return uint16((d >> 16) + 1) - } - return uint16(d >> 16) -} - -func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { - o1 := uint32(0) - o2 := uint32(0) - o3 := uint32(0) - o4 := uint32(0) - o5 := uint32(0) - - //print("%v => case %d\n", p, o->type); - switch o.type_ { - default: - ctxt.Diag("unknown type %d", o.type_) - prasm(p) - - case 0: /* pseudo ops */ - break - - case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */ - if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST { - v := regoff(ctxt, &p.From) - if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { - //nerrors--; - ctxt.Diag("literal operation on R0\n%v", p) - } - - o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v)) - break - } - - o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg)) - - case 2: /* int/cr/fp op Rb,[Ra],Rd */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) - - case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */ - d := vregoff(ctxt, &p.From) - - v := int32(d) - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) { - ctxt.Diag("literal operation on R0\n%v", p) - } - a := OP_ADDI - if o.a1 == C_UCON { - if d&0xffff != 0 { - log.Fatalf("invalid handling of %v", p) - } - v >>= 16 - if r == REGZERO && isuint32(uint64(d)) { - o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v)) - break - } - - a = OP_ADDIS - } else { - if int64(int16(d)) != d { - log.Fatalf("invalid handling of %v", p) - } - } - - o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v)) - - case 4: /* add/mul $scon,[r1],r2 */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 { - ctxt.Diag("literal operation on R0\n%v", p) - } - if int32(int16(v)) != v { - log.Fatalf("mishandled instruction %v", p) - } - o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) - - case 5: /* syscall */ - o1 = oprrr(ctxt, p.As) - - case 6: /* logical op Rb,[Rs,]Ra; no literal */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) - - case 7: /* mov r, soreg ==> stw o(r) */ - r := int(p.To.Reg) - - if r == 0 { - r = int(o.param) - } - v := regoff(ctxt, &p.To) - if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 { - if v != 0 { - ctxt.Diag("illegal indexed instruction\n%v", p) - } - if ctxt.Flag_shared && r == REG_R13 { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - // This (and the matching part in the load case - // below) are the only places in the ppc64 toolchain - // that knows the name of the tls variable. Possibly - // we could add some assembly syntax so that the name - // of the variable does not have to be assumed. - rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0) - rel.Type = obj.R_POWER_TLS - } - o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r)) - } else { - if int32(int16(v)) != v { - log.Fatalf("mishandled instruction %v", p) - } - o1 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(v)) - } - - case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */ - r := int(p.From.Reg) - - if r == 0 { - r = int(o.param) - } - v := regoff(ctxt, &p.From) - if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 { - if v != 0 { - ctxt.Diag("illegal indexed instruction\n%v", p) - } - if ctxt.Flag_shared && r == REG_R13 { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0) - rel.Type = obj.R_POWER_TLS - } - o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r)) - } else { - if int32(int16(v)) != v { - log.Fatalf("mishandled instruction %v", p) - } - o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) - } - - case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */ - r := int(p.From.Reg) - - if r == 0 { - r = int(o.param) - } - v := regoff(ctxt, &p.From) - if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 { - if v != 0 { - ctxt.Diag("illegal indexed instruction\n%v", p) - } - o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r)) - } else { - o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) - } - o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) - - case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r)) - - case 11: /* br/bl lbra */ - v := int32(0) - - if p.Pcond != nil { - v = int32(p.Pcond.Pc - p.Pc) - if v&03 != 0 { - ctxt.Diag("odd branch target address\n%v", p) - v &^= 03 - } - - if v < -(1<<25) || v >= 1<<24 { - ctxt.Diag("branch too far\n%v", p) - } - } - - o1 = OP_BR(opirr(ctxt, p.As), uint32(v), 0) - if p.To.Sym != nil { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - v += int32(p.To.Offset) - if v&03 != 0 { - ctxt.Diag("odd branch target address\n%v", p) - v &^= 03 - } - - rel.Add = int64(v) - rel.Type = obj.R_CALLPOWER - } - o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking - - case 12: /* movb r,r (extsb); movw r,r (extsw) */ - if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST { - v := regoff(ctxt, &p.From) - if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { - ctxt.Diag("literal operation on R0\n%v", p) - } - - o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v)) - break - } - - if p.As == AMOVW { - o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0) - } else { - o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0) - } - - case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */ - if p.As == AMOVBZ { - o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31) - } else if p.As == AMOVH { - o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0) - } else if p.As == AMOVHZ { - o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31) - } else if p.As == AMOVWZ { - o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */ - } else { - ctxt.Diag("internal: bad mov[bhw]z\n%v", p) - } - - case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - d := vregoff(ctxt, p.From3) - var a int - switch p.As { - - // These opcodes expect a mask operand that has to be converted into the - // appropriate operand. The way these were defined, not all valid masks are possible. - // Left here for compatibility in case they were used or generated. - case ARLDCL, ARLDCLCC: - var mask [2]uint8 - maskgen64(ctxt, p, mask[:], uint64(d)) - - a = int(mask[0]) /* MB */ - if mask[1] != 63 { - ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p) - } - - case ARLDCR, ARLDCRCC: - var mask [2]uint8 - maskgen64(ctxt, p, mask[:], uint64(d)) - - a = int(mask[1]) /* ME */ - if mask[0] != 0 { - ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p) - } - - // These opcodes use a shift count like the ppc64 asm, no mask conversion done - case ARLDICR, ARLDICRCC, ARLDICL, ARLDICLCC: - a = int(d) - - default: - ctxt.Diag("unexpected op in rldc case\n%v", p) - a = 0 - } - - o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) - o1 |= (uint32(a) & 31) << 6 - if a&0x20 != 0 { - o1 |= 1 << 5 /* mb[5] is top bit */ - } - - case 17, /* bc bo,bi,lbra (same for now) */ - 16: /* bc bo,bi,sbra */ - a := 0 - - r := int(p.Reg) - - if p.From.Type == obj.TYPE_CONST { - a = int(regoff(ctxt, &p.From)) - } else if p.From.Type == obj.TYPE_REG { - if r != 0 { - ctxt.Diag("unexpected register setting for branch with CR: %d\n", r) - } - // BI values for the CR - switch p.From.Reg { - case REG_CR0: - r = BI_CR0 - case REG_CR1: - r = BI_CR1 - case REG_CR2: - r = BI_CR2 - case REG_CR3: - r = BI_CR3 - case REG_CR4: - r = BI_CR4 - case REG_CR5: - r = BI_CR5 - case REG_CR6: - r = BI_CR6 - case REG_CR7: - r = BI_CR7 - default: - ctxt.Diag("unrecognized register: expecting CR\n") - } - } - v := int32(0) - if p.Pcond != nil { - v = int32(p.Pcond.Pc - p.Pc) - } - if v&03 != 0 { - ctxt.Diag("odd branch target address\n%v", p) - v &^= 03 - } - - if v < -(1<<16) || v >= 1<<15 { - ctxt.Diag("branch too far\n%v", p) - } - o1 = OP_BC(opirr(ctxt, p.As), uint32(a), uint32(r), uint32(v), 0) - - case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */ - var v int32 - if p.As == ABC || p.As == ABCL { - v = regoff(ctxt, &p.To) & 31 - } else { - v = 20 /* unconditional */ - } - o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11 - o2 = OPVCC(19, 16, 0, 0) - if p.As == ABL || p.As == ABCL { - o2 |= 1 - } - o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index)) - - case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */ - var v int32 - if p.As == ABC || p.As == ABCL { - v = regoff(ctxt, &p.From) & 31 - } else { - v = 20 /* unconditional */ - } - r := int(p.Reg) - if r == 0 { - r = 0 - } - switch oclass(&p.To) { - case C_CTR: - o1 = OPVCC(19, 528, 0, 0) - - case C_LR: - o1 = OPVCC(19, 16, 0, 0) - - default: - ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p) - v = 0 - } - - if p.As == ABL || p.As == ABCL { - o1 |= 1 - } - o1 = OP_BCR(o1, uint32(v), uint32(r)) - - case 19: /* mov $lcon,r ==> cau+or */ - d := vregoff(ctxt, &p.From) - - if p.From.Sym == nil { - o1 = loadu32(int(p.To.Reg), d) - o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d))) - } else { - o1, o2 = symbolAccess(ctxt, p.From.Sym, d, p.To.Reg, OP_ADDI) - } - - //if(dlm) reloc(&p->from, p->pc, 0); - - case 20: /* add $ucon,,r */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) { - ctxt.Diag("literal operation on R0\n%v", p) - } - o1 = AOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) - - case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */ - if p.To.Reg == REGTMP || p.Reg == REGTMP { - ctxt.Diag("can't synthesize large constant\n%v", p) - } - d := vregoff(ctxt, &p.From) - o1 = loadu32(REGTMP, d) - o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r)) - if p.From.Sym != nil { - ctxt.Diag("%v is not supported", p) - } - - //if(dlm) reloc(&p->from, p->pc, 0); - - case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */ - if p.To.Reg == REGTMP || p.Reg == REGTMP { - ctxt.Diag("can't synthesize large constant\n%v", p) - } - d := vregoff(ctxt, &p.From) - o1 = loadu32(REGTMP, d) - o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o3 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r)) - if p.From.Sym != nil { - ctxt.Diag("%v is not supported", p) - } - - //if(dlm) reloc(&p->from, p->pc, 0); - - /*24*/ - case 25: - /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */ - v := regoff(ctxt, &p.From) - - if v < 0 { - v = 0 - } else if v > 63 { - v = 63 - } - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - var a int - switch p.As { - case ASLD, ASLDCC: - a = int(63 - v) - o1 = OP_RLDICR - - case ASRD, ASRDCC: - a = int(v) - v = 64 - v - o1 = OP_RLDICL - - default: - ctxt.Diag("unexpected op in sldi case\n%v", p) - a = 0 - o1 = 0 - } - - o1 = AOP_RRR(o1, uint32(r), uint32(p.To.Reg), (uint32(v) & 0x1F)) - o1 |= (uint32(a) & 31) << 6 - if v&0x20 != 0 { - o1 |= 1 << 1 - } - if a&0x20 != 0 { - o1 |= 1 << 5 /* mb[5] is top bit */ - } - if p.As == ASLDCC || p.As == ASRDCC { - o1 |= 1 /* Rc */ - } - - case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */ - if p.To.Reg == REGTMP { - ctxt.Diag("can't synthesize large constant\n%v", p) - } - v := regoff(ctxt, &p.From) - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) - o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v)) - - case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */ - v := regoff(ctxt, p.From3) - - r := int(p.From.Reg) - o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) - - case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */ - if p.To.Reg == REGTMP || p.From.Reg == REGTMP { - ctxt.Diag("can't synthesize large constant\n%v", p) - } - v := regoff(ctxt, p.From3) - o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16) - o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v)) - o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP) - if p.From.Sym != nil { - ctxt.Diag("%v is not supported", p) - } - - //if(dlm) reloc(&p->from3, p->pc, 0); - - case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */ - v := regoff(ctxt, &p.From) - - d := vregoff(ctxt, p.From3) - var mask [2]uint8 - maskgen64(ctxt, p, mask[:], uint64(d)) - var a int - switch p.As { - case ARLDC, ARLDCCC: - a = int(mask[0]) /* MB */ - if int32(mask[1]) != (63 - v) { - ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) - } - - case ARLDCL, ARLDCLCC: - a = int(mask[0]) /* MB */ - if mask[1] != 63 { - ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) - } - - case ARLDCR, ARLDCRCC: - a = int(mask[1]) /* ME */ - if mask[0] != 0 { - ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) - } - - default: - ctxt.Diag("unexpected op in rldic case\n%v", p) - a = 0 - } - - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F)) - o1 |= (uint32(a) & 31) << 6 - if v&0x20 != 0 { - o1 |= 1 << 1 - } - if a&0x20 != 0 { - o1 |= 1 << 5 /* mb[5] is top bit */ - } - - case 30: /* rldimi $sh,s,$mask,a */ - v := regoff(ctxt, &p.From) - - d := vregoff(ctxt, p.From3) - - // Original opcodes had mask operands which had to be converted to a shift count as expected by - // the ppc64 asm. - switch p.As { - case ARLDMI, ARLDMICC: - var mask [2]uint8 - maskgen64(ctxt, p, mask[:], uint64(d)) - if int32(mask[1]) != (63 - v) { - ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p) - } - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F)) - o1 |= (uint32(mask[0]) & 31) << 6 - if v&0x20 != 0 { - o1 |= 1 << 1 - } - if mask[0]&0x20 != 0 { - o1 |= 1 << 5 /* mb[5] is top bit */ - } - - // Opcodes with shift count operands. - case ARLDIMI, ARLDIMICC: - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F)) - o1 |= (uint32(d) & 31) << 6 - if v&0x20 != 0 { - o1 |= 1 << 1 - } - } - - case 31: /* dword */ - d := vregoff(ctxt, &p.From) - - if ctxt.Arch.ByteOrder == binary.BigEndian { - o1 = uint32(d >> 32) - o2 = uint32(d) - } else { - o1 = uint32(d) - o2 = uint32(d >> 32) - } - - if p.From.Sym != nil { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Add = p.From.Offset - rel.Type = obj.R_ADDR - o2 = 0 - o1 = o2 - } - - case 32: /* fmul frc,fra,frd */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6 - - case 33: /* fabs [frb,]frd; fmr. frb,frd */ - r := int(p.From.Reg) - - if oclass(&p.From) == C_NONE { - r = int(p.To.Reg) - } - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(r)) - - case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */ - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6 - - case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */ - v := regoff(ctxt, &p.To) - - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) - o2 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), REGTMP, uint32(v)) - - case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */ - v := regoff(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) - o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v)) - - case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */ - v := regoff(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) - o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v)) - o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) - - case 40: /* word */ - o1 = uint32(regoff(ctxt, &p.From)) - - case 41: /* stswi */ - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11 - - case 42: /* lswi */ - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11 - - case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */ - o1 = AOP_RRR(oprrr(ctxt, p.As), 0, uint32(p.From.Index), uint32(p.From.Reg)) - - case 44: /* indexed store */ - o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg)) - - case 45: /* indexed load */ - o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg)) - - case 46: /* plain op */ - o1 = oprrr(ctxt, p.As) - - case 47: /* op Ra, Rd; also op [Ra,] Rd */ - r := int(p.From.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) - - case 48: /* op Rs, Ra */ - r := int(p.From.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) - - case 49: /* op Rb; op $n, Rb */ - if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */ - v := regoff(ctxt, &p.From) & 1 - o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21 - } else { - o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.From.Reg)) - } - - case 50: /* rem[u] r1[,r2],r3 */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - v := oprrr(ctxt, p.As) - t := v & (1<<10 | 1) /* OE|Rc */ - o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg)) - o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg)) - o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r)) - if p.As == AREMU { - o4 = o3 - - /* Clear top 32 bits */ - o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5 - } - - case 51: /* remd[u] r1[,r2],r3 */ - r := int(p.Reg) - - if r == 0 { - r = int(p.To.Reg) - } - v := oprrr(ctxt, p.As) - t := v & (1<<10 | 1) /* OE|Rc */ - o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg)) - o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg)) - o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r)) - - case 52: /* mtfsbNx cr(n) */ - v := regoff(ctxt, &p.From) & 31 - - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(v), 0, 0) - - case 53: /* mffsX ,fr1 */ - o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0) - - case 54: /* mov msr,r1; mov r1, msr*/ - if oclass(&p.From) == C_REG { - if p.As == AMOVD { - o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0) - } else { - o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0) - } - } else { - o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0) - } - - case 55: /* op Rb, Rd */ - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg)) - - case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31) - if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) { - o1 |= 1 << 1 /* mb[5] */ - } - - case 57: /* slw $sh,[s,]a -> rlwinm ... */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - - /* - * Let user (gs) shoot himself in the foot. - * qc has already complained. - * - if(v < 0 || v > 31) - ctxt->diag("illegal shift %ld\n%v", v, p); - */ - if v < 0 { - v = 0 - } else if v > 32 { - v = 32 - } - var mask [2]uint8 - if p.As == ASRW || p.As == ASRWCC { /* shift right */ - mask[0] = uint8(v) - mask[1] = 31 - v = 32 - v - } else { - mask[0] = 0 - mask[1] = uint8(31 - v) - } - - o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1])) - if p.As == ASLWCC || p.As == ASRWCC { - o1 |= 1 /* Rc */ - } - - case 58: /* logical $andcon,[s],a */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 = LOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v)) - - case 59: /* or/and $ucon,,r */ - v := regoff(ctxt, &p.From) - - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 = LOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */ - - case 60: /* tw to,a,b */ - r := int(regoff(ctxt, &p.From) & 31) - - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg)) - - case 61: /* tw to,a,$simm */ - r := int(regoff(ctxt, &p.From) & 31) - - v := regoff(ctxt, &p.To) - o1 = AOP_IRR(opirr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(v)) - - case 62: /* rlwmi $sh,s,$mask,a */ - v := regoff(ctxt, &p.From) - - var mask [2]uint8 - maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3))) - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v)) - o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 - - case 63: /* rlwmi b,s,$mask,a */ - var mask [2]uint8 - maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3))) - - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg)) - o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 - - case 64: /* mtfsf fr[, $m] {,fpcsr} */ - var v int32 - if p.From3Type() != obj.TYPE_NONE { - v = regoff(ctxt, p.From3) & 255 - } else { - v = 255 - } - o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11 - - case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */ - if p.To.Reg == 0 { - ctxt.Diag("must specify FPSCR(n)\n%v", p) - } - o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12 - - case 66: /* mov spr,r1; mov r1,spr, also dcr */ - var r int - var v int32 - if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 { - r = int(p.From.Reg) - v = int32(p.To.Reg) - if REG_DCR0 <= v && v <= REG_DCR0+1023 { - o1 = OPVCC(31, 451, 0, 0) /* mtdcr */ - } else { - o1 = OPVCC(31, 467, 0, 0) /* mtspr */ - } - } else { - r = int(p.To.Reg) - v = int32(p.From.Reg) - if REG_DCR0 <= v && v <= REG_DCR0+1023 { - o1 = OPVCC(31, 323, 0, 0) /* mfdcr */ - } else { - o1 = OPVCC(31, 339, 0, 0) /* mfspr */ - } - } - - o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11 - - case 67: /* mcrf crfD,crfS */ - if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg { - ctxt.Diag("illegal CR field number\n%v", p) - } - o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0) - - case 68: /* mfcr rD; mfocrf CRM,rD */ - if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 { - v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */ - o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */ - } else { - o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */ - } - - case 69: /* mtcrf CRM,rS */ - var v int32 - if p.From3Type() != obj.TYPE_NONE { - if p.To.Reg != 0 { - ctxt.Diag("can't use both mask and CR(n)\n%v", p) - } - v = regoff(ctxt, p.From3) & 0xff - } else { - if p.To.Reg == 0 { - v = 0xff /* CR */ - } else { - v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */ - } - } - - o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12 - - case 70: /* [f]cmp r,r,cr*/ - var r int - if p.Reg == 0 { - r = 0 - } else { - r = (int(p.Reg) & 7) << 2 - } - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg)) - - case 71: /* cmp[l] r,i,cr*/ - var r int - if p.Reg == 0 { - r = 0 - } else { - r = (int(p.Reg) & 7) << 2 - } - o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff - - case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */ - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg)) - - case 73: /* mcrfs crfD,crfS */ - if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg { - ctxt.Diag("illegal FPSCR/CR field number\n%v", p) - } - o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0) - - case 77: /* syscall $scon, syscall Rx */ - if p.From.Type == obj.TYPE_CONST { - if p.From.Offset > BIG || p.From.Offset < -BIG { - ctxt.Diag("illegal syscall, sysnum too large: %v", p) - } - o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset)) - } else if p.From.Type == obj.TYPE_REG { - o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg)) - } else { - ctxt.Diag("illegal syscall: %v", p) - o1 = 0x7fe00008 // trap always - } - - o2 = oprrr(ctxt, p.As) - o3 = AOP_RRR(oprrr(ctxt, AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0 - - case 78: /* undef */ - o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed - always to be an illegal instruction." */ - - /* relocation operations */ - case 74: - v := vregoff(ctxt, &p.To) - o1, o2 = symbolAccess(ctxt, p.To.Sym, v, p.From.Reg, opstore(ctxt, p.As)) - - //if(dlm) reloc(&p->to, p->pc, 1); - - case 75: - v := vregoff(ctxt, &p.From) - o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As)) - - //if(dlm) reloc(&p->from, p->pc, 1); - - case 76: - v := vregoff(ctxt, &p.From) - o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As)) - o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) - - //if(dlm) reloc(&p->from, p->pc, 1); - - case 79: - if p.From.Offset != 0 { - ctxt.Diag("invalid offset against tls var %v", p) - } - o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Type = obj.R_POWER_TLS_LE - - case 80: - if p.From.Offset != 0 { - ctxt.Diag("invalid offset against tls var %v", p) - } - o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0) - o2 = AOP_IRR(opload(ctxt, AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Type = obj.R_POWER_TLS_IE - - case 81: - v := vregoff(ctxt, &p.To) - if v != 0 { - ctxt.Diag("invalid offset against GOT slot %v", p) - } - - o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0) - o2 = AOP_IRR(opload(ctxt, AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Type = obj.R_ADDRPOWER_GOT - case 82: /* vector instructions, VX-form and VC-form */ - if p.From.Type == obj.TYPE_REG { - /* reg reg none OR reg reg reg */ - /* 3-register operand order: VRA, VRB, VRT */ - /* 2-register operand order: VRA, VRT */ - o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) - } else if p.From3Type() == obj.TYPE_CONST { - /* imm imm reg reg */ - /* operand order: SIX, VRA, ST, VRT */ - six := int(regoff(ctxt, &p.From)) - st := int(regoff(ctxt, p.From3)) - o1 = AOP_IIRR(opiirr(ctxt, p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six)) - } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 { - /* imm reg reg */ - /* operand order: UIM, VRB, VRT */ - uim := int(regoff(ctxt, &p.From)) - o1 = AOP_VIRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim)) - } else { - /* imm reg */ - /* operand order: SIM, VRT */ - sim := int(regoff(ctxt, &p.From)) - o1 = AOP_IR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(sim)) - } - - case 83: /* vector instructions, VA-form */ - if p.From.Type == obj.TYPE_REG { - /* reg reg reg reg */ - /* 4-register operand order: VRA, VRB, VRC, VRT */ - o1 = AOP_RRRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.From3.Reg)) - } else if p.From.Type == obj.TYPE_CONST { - /* imm reg reg reg */ - /* operand order: SHB, VRA, VRB, VRT */ - shb := int(regoff(ctxt, &p.From)) - o1 = AOP_IRRR(opirrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), uint32(shb)) - } - - case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc - bc := vregoff(ctxt, &p.From) - - // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg - o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), uint32(bc)) - - case 85: /* vector instructions, VX-form */ - /* reg none reg */ - /* 2-register operand order: VRB, VRT */ - o1 = AOP_RR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg)) - - case 86: /* VSX indexed store, XX1-form */ - /* reg reg reg */ - /* 3-register operand order: XT, (RB)(RA*1) */ - o1 = AOP_XX1(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg)) - - case 87: /* VSX indexed load, XX1-form */ - /* reg reg reg */ - /* 3-register operand order: (RB)(RA*1), XT */ - o1 = AOP_XX1(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg)) - - case 88: /* VSX instructions, XX1-form */ - /* reg reg none OR reg reg reg */ - /* 3-register operand order: RA, RB, XT */ - /* 2-register operand order: XS, RA or RA, XT */ - xt := int32(p.To.Reg) - xs := int32(p.From.Reg) - if REG_VS0 <= xt && xt <= REG_VS63 { - o1 = AOP_XX1(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) - } else if REG_VS0 <= xs && xs <= REG_VS63 { - o1 = AOP_XX1(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg)) - } - - case 89: /* VSX instructions, XX2-form */ - /* reg none reg OR reg imm reg */ - /* 2-register operand order: XB, XT or XB, UIM, XT*/ - uim := int(regoff(ctxt, p.From3)) - o1 = AOP_XX2(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg)) - - case 90: /* VSX instructions, XX3-form */ - if p.From3Type() == obj.TYPE_NONE { - /* reg reg reg */ - /* 3-register operand order: XA, XB, XT */ - o1 = AOP_XX3(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) - } else if p.From3Type() == obj.TYPE_CONST { - /* reg reg reg imm */ - /* operand order: XA, XB, DM, XT */ - dm := int(regoff(ctxt, p.From3)) - o1 = AOP_XX3I(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm)) - } - - case 91: /* VSX instructions, XX4-form */ - /* reg reg reg reg */ - /* 3-register operand order: XA, XB, XC, XT */ - o1 = AOP_XX4(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.From3.Reg)) - - } - - out[0] = o1 - out[1] = o2 - out[2] = o3 - out[3] = o4 - out[4] = o5 - return -} - -func vregoff(ctxt *obj.Link, a *obj.Addr) int64 { - ctxt.Instoffset = 0 - if a != nil { - aclass(ctxt, a) - } - return ctxt.Instoffset -} - -func regoff(ctxt *obj.Link, a *obj.Addr) int32 { - return int32(vregoff(ctxt, a)) -} - -func oprrr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AADD: - return OPVCC(31, 266, 0, 0) - case AADDCC: - return OPVCC(31, 266, 0, 1) - case AADDV: - return OPVCC(31, 266, 1, 0) - case AADDVCC: - return OPVCC(31, 266, 1, 1) - case AADDC: - return OPVCC(31, 10, 0, 0) - case AADDCCC: - return OPVCC(31, 10, 0, 1) - case AADDCV: - return OPVCC(31, 10, 1, 0) - case AADDCVCC: - return OPVCC(31, 10, 1, 1) - case AADDE: - return OPVCC(31, 138, 0, 0) - case AADDECC: - return OPVCC(31, 138, 0, 1) - case AADDEV: - return OPVCC(31, 138, 1, 0) - case AADDEVCC: - return OPVCC(31, 138, 1, 1) - case AADDME: - return OPVCC(31, 234, 0, 0) - case AADDMECC: - return OPVCC(31, 234, 0, 1) - case AADDMEV: - return OPVCC(31, 234, 1, 0) - case AADDMEVCC: - return OPVCC(31, 234, 1, 1) - case AADDZE: - return OPVCC(31, 202, 0, 0) - case AADDZECC: - return OPVCC(31, 202, 0, 1) - case AADDZEV: - return OPVCC(31, 202, 1, 0) - case AADDZEVCC: - return OPVCC(31, 202, 1, 1) - - case AAND: - return OPVCC(31, 28, 0, 0) - case AANDCC: - return OPVCC(31, 28, 0, 1) - case AANDN: - return OPVCC(31, 60, 0, 0) - case AANDNCC: - return OPVCC(31, 60, 0, 1) - - case ACMP: - return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */ - case ACMPU: - return OPVCC(31, 32, 0, 0) | 1<<21 - case ACMPW: - return OPVCC(31, 0, 0, 0) /* L=0 */ - case ACMPWU: - return OPVCC(31, 32, 0, 0) - - case ACNTLZW: - return OPVCC(31, 26, 0, 0) - case ACNTLZWCC: - return OPVCC(31, 26, 0, 1) - case ACNTLZD: - return OPVCC(31, 58, 0, 0) - case ACNTLZDCC: - return OPVCC(31, 58, 0, 1) - - case ACRAND: - return OPVCC(19, 257, 0, 0) - case ACRANDN: - return OPVCC(19, 129, 0, 0) - case ACREQV: - return OPVCC(19, 289, 0, 0) - case ACRNAND: - return OPVCC(19, 225, 0, 0) - case ACRNOR: - return OPVCC(19, 33, 0, 0) - case ACROR: - return OPVCC(19, 449, 0, 0) - case ACRORN: - return OPVCC(19, 417, 0, 0) - case ACRXOR: - return OPVCC(19, 193, 0, 0) - - case ADCBF: - return OPVCC(31, 86, 0, 0) - case ADCBI: - return OPVCC(31, 470, 0, 0) - case ADCBST: - return OPVCC(31, 54, 0, 0) - case ADCBT: - return OPVCC(31, 278, 0, 0) - case ADCBTST: - return OPVCC(31, 246, 0, 0) - case ADCBZ: - return OPVCC(31, 1014, 0, 0) - - case AREM, ADIVW: - return OPVCC(31, 491, 0, 0) - - case AREMCC, ADIVWCC: - return OPVCC(31, 491, 0, 1) - - case AREMV, ADIVWV: - return OPVCC(31, 491, 1, 0) - - case AREMVCC, ADIVWVCC: - return OPVCC(31, 491, 1, 1) - - case AREMU, ADIVWU: - return OPVCC(31, 459, 0, 0) - - case AREMUCC, ADIVWUCC: - return OPVCC(31, 459, 0, 1) - - case AREMUV, ADIVWUV: - return OPVCC(31, 459, 1, 0) - - case AREMUVCC, ADIVWUVCC: - return OPVCC(31, 459, 1, 1) - - case AREMD, ADIVD: - return OPVCC(31, 489, 0, 0) - - case AREMDCC, ADIVDCC: - return OPVCC(31, 489, 0, 1) - - case ADIVDE: - return OPVCC(31, 425, 0, 0) - - case ADIVDECC: - return OPVCC(31, 425, 0, 1) - - case ADIVDEU: - return OPVCC(31, 393, 0, 0) - - case ADIVDEUCC: - return OPVCC(31, 393, 0, 1) - - case AREMDV, ADIVDV: - return OPVCC(31, 489, 1, 0) - - case AREMDVCC, ADIVDVCC: - return OPVCC(31, 489, 1, 1) - - case AREMDU, ADIVDU: - return OPVCC(31, 457, 0, 0) - - case AREMDUCC, ADIVDUCC: - return OPVCC(31, 457, 0, 1) - - case AREMDUV, ADIVDUV: - return OPVCC(31, 457, 1, 0) - - case AREMDUVCC, ADIVDUVCC: - return OPVCC(31, 457, 1, 1) - - case AEIEIO: - return OPVCC(31, 854, 0, 0) - - case AEQV: - return OPVCC(31, 284, 0, 0) - case AEQVCC: - return OPVCC(31, 284, 0, 1) - - case AEXTSB: - return OPVCC(31, 954, 0, 0) - case AEXTSBCC: - return OPVCC(31, 954, 0, 1) - case AEXTSH: - return OPVCC(31, 922, 0, 0) - case AEXTSHCC: - return OPVCC(31, 922, 0, 1) - case AEXTSW: - return OPVCC(31, 986, 0, 0) - case AEXTSWCC: - return OPVCC(31, 986, 0, 1) - - case AFABS: - return OPVCC(63, 264, 0, 0) - case AFABSCC: - return OPVCC(63, 264, 0, 1) - case AFADD: - return OPVCC(63, 21, 0, 0) - case AFADDCC: - return OPVCC(63, 21, 0, 1) - case AFADDS: - return OPVCC(59, 21, 0, 0) - case AFADDSCC: - return OPVCC(59, 21, 0, 1) - case AFCMPO: - return OPVCC(63, 32, 0, 0) - case AFCMPU: - return OPVCC(63, 0, 0, 0) - case AFCFID: - return OPVCC(63, 846, 0, 0) - case AFCFIDCC: - return OPVCC(63, 846, 0, 1) - case AFCFIDU: - return OPVCC(63, 974, 0, 0) - case AFCFIDUCC: - return OPVCC(63, 974, 0, 1) - case AFCTIW: - return OPVCC(63, 14, 0, 0) - case AFCTIWCC: - return OPVCC(63, 14, 0, 1) - case AFCTIWZ: - return OPVCC(63, 15, 0, 0) - case AFCTIWZCC: - return OPVCC(63, 15, 0, 1) - case AFCTID: - return OPVCC(63, 814, 0, 0) - case AFCTIDCC: - return OPVCC(63, 814, 0, 1) - case AFCTIDZ: - return OPVCC(63, 815, 0, 0) - case AFCTIDZCC: - return OPVCC(63, 815, 0, 1) - case AFDIV: - return OPVCC(63, 18, 0, 0) - case AFDIVCC: - return OPVCC(63, 18, 0, 1) - case AFDIVS: - return OPVCC(59, 18, 0, 0) - case AFDIVSCC: - return OPVCC(59, 18, 0, 1) - case AFMADD: - return OPVCC(63, 29, 0, 0) - case AFMADDCC: - return OPVCC(63, 29, 0, 1) - case AFMADDS: - return OPVCC(59, 29, 0, 0) - case AFMADDSCC: - return OPVCC(59, 29, 0, 1) - - case AFMOVS, AFMOVD: - return OPVCC(63, 72, 0, 0) /* load */ - case AFMOVDCC: - return OPVCC(63, 72, 0, 1) - case AFMSUB: - return OPVCC(63, 28, 0, 0) - case AFMSUBCC: - return OPVCC(63, 28, 0, 1) - case AFMSUBS: - return OPVCC(59, 28, 0, 0) - case AFMSUBSCC: - return OPVCC(59, 28, 0, 1) - case AFMUL: - return OPVCC(63, 25, 0, 0) - case AFMULCC: - return OPVCC(63, 25, 0, 1) - case AFMULS: - return OPVCC(59, 25, 0, 0) - case AFMULSCC: - return OPVCC(59, 25, 0, 1) - case AFNABS: - return OPVCC(63, 136, 0, 0) - case AFNABSCC: - return OPVCC(63, 136, 0, 1) - case AFNEG: - return OPVCC(63, 40, 0, 0) - case AFNEGCC: - return OPVCC(63, 40, 0, 1) - case AFNMADD: - return OPVCC(63, 31, 0, 0) - case AFNMADDCC: - return OPVCC(63, 31, 0, 1) - case AFNMADDS: - return OPVCC(59, 31, 0, 0) - case AFNMADDSCC: - return OPVCC(59, 31, 0, 1) - case AFNMSUB: - return OPVCC(63, 30, 0, 0) - case AFNMSUBCC: - return OPVCC(63, 30, 0, 1) - case AFNMSUBS: - return OPVCC(59, 30, 0, 0) - case AFNMSUBSCC: - return OPVCC(59, 30, 0, 1) - case AFRES: - return OPVCC(59, 24, 0, 0) - case AFRESCC: - return OPVCC(59, 24, 0, 1) - case AFRIM: - return OPVCC(63, 488, 0, 0) - case AFRIMCC: - return OPVCC(63, 488, 0, 1) - case AFRIP: - return OPVCC(63, 456, 0, 0) - case AFRIPCC: - return OPVCC(63, 456, 0, 1) - case AFRIZ: - return OPVCC(63, 424, 0, 0) - case AFRIZCC: - return OPVCC(63, 424, 0, 1) - case AFRSP: - return OPVCC(63, 12, 0, 0) - case AFRSPCC: - return OPVCC(63, 12, 0, 1) - case AFRSQRTE: - return OPVCC(63, 26, 0, 0) - case AFRSQRTECC: - return OPVCC(63, 26, 0, 1) - case AFSEL: - return OPVCC(63, 23, 0, 0) - case AFSELCC: - return OPVCC(63, 23, 0, 1) - case AFSQRT: - return OPVCC(63, 22, 0, 0) - case AFSQRTCC: - return OPVCC(63, 22, 0, 1) - case AFSQRTS: - return OPVCC(59, 22, 0, 0) - case AFSQRTSCC: - return OPVCC(59, 22, 0, 1) - case AFSUB: - return OPVCC(63, 20, 0, 0) - case AFSUBCC: - return OPVCC(63, 20, 0, 1) - case AFSUBS: - return OPVCC(59, 20, 0, 0) - case AFSUBSCC: - return OPVCC(59, 20, 0, 1) - - case AICBI: - return OPVCC(31, 982, 0, 0) - case AISYNC: - return OPVCC(19, 150, 0, 0) - - case AMTFSB0: - return OPVCC(63, 70, 0, 0) - case AMTFSB0CC: - return OPVCC(63, 70, 0, 1) - case AMTFSB1: - return OPVCC(63, 38, 0, 0) - case AMTFSB1CC: - return OPVCC(63, 38, 0, 1) - - case AMULHW: - return OPVCC(31, 75, 0, 0) - case AMULHWCC: - return OPVCC(31, 75, 0, 1) - case AMULHWU: - return OPVCC(31, 11, 0, 0) - case AMULHWUCC: - return OPVCC(31, 11, 0, 1) - case AMULLW: - return OPVCC(31, 235, 0, 0) - case AMULLWCC: - return OPVCC(31, 235, 0, 1) - case AMULLWV: - return OPVCC(31, 235, 1, 0) - case AMULLWVCC: - return OPVCC(31, 235, 1, 1) - - case AMULHD: - return OPVCC(31, 73, 0, 0) - case AMULHDCC: - return OPVCC(31, 73, 0, 1) - case AMULHDU: - return OPVCC(31, 9, 0, 0) - case AMULHDUCC: - return OPVCC(31, 9, 0, 1) - case AMULLD: - return OPVCC(31, 233, 0, 0) - case AMULLDCC: - return OPVCC(31, 233, 0, 1) - case AMULLDV: - return OPVCC(31, 233, 1, 0) - case AMULLDVCC: - return OPVCC(31, 233, 1, 1) - - case ANAND: - return OPVCC(31, 476, 0, 0) - case ANANDCC: - return OPVCC(31, 476, 0, 1) - case ANEG: - return OPVCC(31, 104, 0, 0) - case ANEGCC: - return OPVCC(31, 104, 0, 1) - case ANEGV: - return OPVCC(31, 104, 1, 0) - case ANEGVCC: - return OPVCC(31, 104, 1, 1) - case ANOR: - return OPVCC(31, 124, 0, 0) - case ANORCC: - return OPVCC(31, 124, 0, 1) - case AOR: - return OPVCC(31, 444, 0, 0) - case AORCC: - return OPVCC(31, 444, 0, 1) - case AORN: - return OPVCC(31, 412, 0, 0) - case AORNCC: - return OPVCC(31, 412, 0, 1) - - case ARFI: - return OPVCC(19, 50, 0, 0) - case ARFCI: - return OPVCC(19, 51, 0, 0) - case ARFID: - return OPVCC(19, 18, 0, 0) - case AHRFID: - return OPVCC(19, 274, 0, 0) - - case ARLWMI: - return OPVCC(20, 0, 0, 0) - case ARLWMICC: - return OPVCC(20, 0, 0, 1) - case ARLWNM: - return OPVCC(23, 0, 0, 0) - case ARLWNMCC: - return OPVCC(23, 0, 0, 1) - - case ARLDCL: - return OPVCC(30, 8, 0, 0) - case ARLDCR: - return OPVCC(30, 9, 0, 0) - - case ARLDICL: - return OPVCC(30, 0, 0, 0) - case ARLDICLCC: - return OPVCC(30, 0, 0, 1) - case ARLDICR: - return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr - case ARLDICRCC: - return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr. - - case ASYSCALL: - return OPVCC(17, 1, 0, 0) - - case ASLW: - return OPVCC(31, 24, 0, 0) - case ASLWCC: - return OPVCC(31, 24, 0, 1) - case ASLD: - return OPVCC(31, 27, 0, 0) - case ASLDCC: - return OPVCC(31, 27, 0, 1) - - case ASRAW: - return OPVCC(31, 792, 0, 0) - case ASRAWCC: - return OPVCC(31, 792, 0, 1) - case ASRAD: - return OPVCC(31, 794, 0, 0) - case ASRADCC: - return OPVCC(31, 794, 0, 1) - - case ASRW: - return OPVCC(31, 536, 0, 0) - case ASRWCC: - return OPVCC(31, 536, 0, 1) - case ASRD: - return OPVCC(31, 539, 0, 0) - case ASRDCC: - return OPVCC(31, 539, 0, 1) - - case ASUB: - return OPVCC(31, 40, 0, 0) - case ASUBCC: - return OPVCC(31, 40, 0, 1) - case ASUBV: - return OPVCC(31, 40, 1, 0) - case ASUBVCC: - return OPVCC(31, 40, 1, 1) - case ASUBC: - return OPVCC(31, 8, 0, 0) - case ASUBCCC: - return OPVCC(31, 8, 0, 1) - case ASUBCV: - return OPVCC(31, 8, 1, 0) - case ASUBCVCC: - return OPVCC(31, 8, 1, 1) - case ASUBE: - return OPVCC(31, 136, 0, 0) - case ASUBECC: - return OPVCC(31, 136, 0, 1) - case ASUBEV: - return OPVCC(31, 136, 1, 0) - case ASUBEVCC: - return OPVCC(31, 136, 1, 1) - case ASUBME: - return OPVCC(31, 232, 0, 0) - case ASUBMECC: - return OPVCC(31, 232, 0, 1) - case ASUBMEV: - return OPVCC(31, 232, 1, 0) - case ASUBMEVCC: - return OPVCC(31, 232, 1, 1) - case ASUBZE: - return OPVCC(31, 200, 0, 0) - case ASUBZECC: - return OPVCC(31, 200, 0, 1) - case ASUBZEV: - return OPVCC(31, 200, 1, 0) - case ASUBZEVCC: - return OPVCC(31, 200, 1, 1) - - case ASYNC: - return OPVCC(31, 598, 0, 0) - case ALWSYNC: - return OPVCC(31, 598, 0, 0) | 1<<21 - - case APTESYNC: - return OPVCC(31, 598, 0, 0) | 2<<21 - - case ATLBIE: - return OPVCC(31, 306, 0, 0) - case ATLBIEL: - return OPVCC(31, 274, 0, 0) - case ATLBSYNC: - return OPVCC(31, 566, 0, 0) - case ASLBIA: - return OPVCC(31, 498, 0, 0) - case ASLBIE: - return OPVCC(31, 434, 0, 0) - case ASLBMFEE: - return OPVCC(31, 915, 0, 0) - case ASLBMFEV: - return OPVCC(31, 851, 0, 0) - case ASLBMTE: - return OPVCC(31, 402, 0, 0) - - case ATW: - return OPVCC(31, 4, 0, 0) - case ATD: - return OPVCC(31, 68, 0, 0) - - /* Vector (VMX/Altivec) instructions */ - /* ISA 2.03 enables these for PPC970. For POWERx processors, these */ - /* are enabled starting at POWER6 (ISA 2.05). */ - case AVANDL: - return OPVX(4, 1028, 0, 0) /* vand - v2.03 */ - case AVANDC: - return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */ - case AVNAND: - return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */ - - case AVORL: - return OPVX(4, 1156, 0, 0) /* vor - v2.03 */ - case AVORC: - return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */ - case AVNOR: - return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */ - case AVXOR: - return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */ - case AVEQV: - return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */ - - case AVADDUBM: - return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */ - case AVADDUHM: - return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */ - case AVADDUWM: - return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */ - case AVADDUDM: - return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */ - case AVADDUQM: - return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */ - - case AVADDCUQ: - return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */ - case AVADDCUW: - return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */ - - case AVADDUBS: - return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */ - case AVADDUHS: - return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */ - case AVADDUWS: - return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */ - - case AVADDSBS: - return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */ - case AVADDSHS: - return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */ - case AVADDSWS: - return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */ - - case AVADDEUQM: - return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */ - case AVADDECUQ: - return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */ - - case AVSUBUBM: - return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */ - case AVSUBUHM: - return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */ - case AVSUBUWM: - return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */ - case AVSUBUDM: - return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */ - case AVSUBUQM: - return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */ - - case AVSUBCUQ: - return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */ - case AVSUBCUW: - return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */ - - case AVSUBUBS: - return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */ - case AVSUBUHS: - return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */ - case AVSUBUWS: - return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */ - - case AVSUBSBS: - return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */ - case AVSUBSHS: - return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */ - case AVSUBSWS: - return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */ - - case AVSUBEUQM: - return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */ - case AVSUBECUQ: - return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */ - - case AVRLB: - return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */ - case AVRLH: - return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */ - case AVRLW: - return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */ - case AVRLD: - return OPVX(4, 196, 0, 0) /* vrld - v2.07 */ - - case AVSLB: - return OPVX(4, 260, 0, 0) /* vslh - v2.03 */ - case AVSLH: - return OPVX(4, 324, 0, 0) /* vslh - v2.03 */ - case AVSLW: - return OPVX(4, 388, 0, 0) /* vslw - v2.03 */ - case AVSL: - return OPVX(4, 452, 0, 0) /* vsl - v2.03 */ - case AVSLO: - return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */ - case AVSRB: - return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */ - case AVSRH: - return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */ - case AVSRW: - return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */ - case AVSR: - return OPVX(4, 708, 0, 0) /* vsr - v2.03 */ - case AVSRO: - return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */ - case AVSLD: - return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */ - case AVSRD: - return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */ - - case AVSRAB: - return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */ - case AVSRAH: - return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */ - case AVSRAW: - return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */ - case AVSRAD: - return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */ - - case AVCLZB: - return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */ - case AVCLZH: - return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */ - case AVCLZW: - return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */ - case AVCLZD: - return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */ - - case AVPOPCNTB: - return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */ - case AVPOPCNTH: - return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */ - case AVPOPCNTW: - return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */ - case AVPOPCNTD: - return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */ - - case AVCMPEQUB: - return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */ - case AVCMPEQUBCC: - return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */ - case AVCMPEQUH: - return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */ - case AVCMPEQUHCC: - return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */ - case AVCMPEQUW: - return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */ - case AVCMPEQUWCC: - return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */ - case AVCMPEQUD: - return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */ - case AVCMPEQUDCC: - return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */ - - case AVCMPGTUB: - return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */ - case AVCMPGTUBCC: - return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */ - case AVCMPGTUH: - return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */ - case AVCMPGTUHCC: - return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */ - case AVCMPGTUW: - return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */ - case AVCMPGTUWCC: - return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */ - case AVCMPGTUD: - return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */ - case AVCMPGTUDCC: - return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */ - case AVCMPGTSB: - return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */ - case AVCMPGTSBCC: - return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */ - case AVCMPGTSH: - return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */ - case AVCMPGTSHCC: - return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */ - case AVCMPGTSW: - return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */ - case AVCMPGTSWCC: - return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */ - case AVCMPGTSD: - return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */ - case AVCMPGTSDCC: - return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */ - - case AVPERM: - return OPVX(4, 43, 0, 0) /* vperm - v2.03 */ - - case AVSEL: - return OPVX(4, 42, 0, 0) /* vsel - v2.03 */ - - case AVCIPHER: - return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */ - case AVCIPHERLAST: - return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */ - case AVNCIPHER: - return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */ - case AVNCIPHERLAST: - return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */ - case AVSBOX: - return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */ - /* End of vector instructions */ - - /* Vector scalar (VSX) instructions */ - /* ISA 2.06 enables these for POWER7. */ - case AMFVSRD: - return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */ - case AMFVSRWZ: - return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */ - - case AMTVSRD: - return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */ - case AMTVSRWA: - return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */ - case AMTVSRWZ: - return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */ - - case AXXLANDQ: - return OPVXX3(60, 130, 0) /* xxland - v2.06 */ - case AXXLANDC: - return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */ - case AXXLEQV: - return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */ - case AXXLNAND: - return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */ - - case AXXLORC: - return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */ - case AXXLNOR: - return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */ - case AXXLORQ: - return OPVXX3(60, 146, 0) /* xxlor - v2.06 */ - case AXXLXOR: - return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */ - - case AXXSEL: - return OPVXX4(60, 3, 0) /* xxsel - v2.06 */ - - case AXXMRGHW: - return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */ - case AXXMRGLW: - return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */ - - case AXXSPLTW: - return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */ - - case AXXPERMDI: - return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */ - - case AXXSLDWI: - return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */ - - case AXSCVDPSP: - return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */ - case AXSCVSPDP: - return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */ - case AXSCVDPSPN: - return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */ - case AXSCVSPDPN: - return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */ - - case AXVCVDPSP: - return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */ - case AXVCVSPDP: - return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */ - - case AXSCVDPSXDS: - return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */ - case AXSCVDPSXWS: - return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */ - case AXSCVDPUXDS: - return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */ - case AXSCVDPUXWS: - return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */ - - case AXSCVSXDDP: - return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */ - case AXSCVUXDDP: - return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */ - case AXSCVSXDSP: - return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */ - case AXSCVUXDSP: - return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */ - - case AXVCVDPSXDS: - return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */ - case AXVCVDPSXWS: - return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */ - case AXVCVDPUXDS: - return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */ - case AXVCVDPUXWS: - return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */ - case AXVCVSPSXDS: - return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */ - case AXVCVSPSXWS: - return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */ - case AXVCVSPUXDS: - return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */ - case AXVCVSPUXWS: - return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */ - - case AXVCVSXDDP: - return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */ - case AXVCVSXWDP: - return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */ - case AXVCVUXDDP: - return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */ - case AXVCVUXWDP: - return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */ - case AXVCVSXDSP: - return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */ - case AXVCVSXWSP: - return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */ - case AXVCVUXDSP: - return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */ - case AXVCVUXWSP: - return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */ - /* End of VSX instructions */ - - case AXOR: - return OPVCC(31, 316, 0, 0) - case AXORCC: - return OPVCC(31, 316, 0, 1) - } - - ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a) - return 0 -} - -func opirrr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - /* Vector (VMX/Altivec) instructions */ - /* ISA 2.03 enables these for PPC970. For POWERx processors, these */ - /* are enabled starting at POWER6 (ISA 2.05). */ - case AVSLDOI: - return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */ - } - - ctxt.Diag("bad i/r/r/r opcode %v", a) - return 0 -} - -func opiirr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - /* Vector (VMX/Altivec) instructions */ - /* ISA 2.07 enables these for POWER8 and beyond. */ - case AVSHASIGMAW: - return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */ - case AVSHASIGMAD: - return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */ - } - - ctxt.Diag("bad i/i/r/r opcode %v", a) - return 0 -} - -func opirr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AADD: - return OPVCC(14, 0, 0, 0) - case AADDC: - return OPVCC(12, 0, 0, 0) - case AADDCCC: - return OPVCC(13, 0, 0, 0) - case -AADD: - return OPVCC(15, 0, 0, 0) /* ADDIS/CAU */ - - case AANDCC: - return OPVCC(28, 0, 0, 0) - case -AANDCC: - return OPVCC(29, 0, 0, 0) /* ANDIS./ANDIU. */ - - case ABR: - return OPVCC(18, 0, 0, 0) - case ABL: - return OPVCC(18, 0, 0, 0) | 1 - case obj.ADUFFZERO: - return OPVCC(18, 0, 0, 0) | 1 - case obj.ADUFFCOPY: - return OPVCC(18, 0, 0, 0) | 1 - case ABC: - return OPVCC(16, 0, 0, 0) - case ABCL: - return OPVCC(16, 0, 0, 0) | 1 - - case ABEQ: - return AOP_RRR(16<<26, 12, 2, 0) - case ABGE: - return AOP_RRR(16<<26, 4, 0, 0) - case ABGT: - return AOP_RRR(16<<26, 12, 1, 0) - case ABLE: - return AOP_RRR(16<<26, 4, 1, 0) - case ABLT: - return AOP_RRR(16<<26, 12, 0, 0) - case ABNE: - return AOP_RRR(16<<26, 4, 2, 0) - case ABVC: - return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear - case ABVS: - return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set - - case ACMP: - return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */ - case ACMPU: - return OPVCC(10, 0, 0, 0) | 1<<21 - case ACMPW: - return OPVCC(11, 0, 0, 0) /* L=0 */ - case ACMPWU: - return OPVCC(10, 0, 0, 0) - case ALSW: - return OPVCC(31, 597, 0, 0) - - case AMULLW: - return OPVCC(7, 0, 0, 0) - - case AOR: - return OPVCC(24, 0, 0, 0) - case -AOR: - return OPVCC(25, 0, 0, 0) /* ORIS/ORIU */ - - case ARLWMI: - return OPVCC(20, 0, 0, 0) /* rlwimi */ - case ARLWMICC: - return OPVCC(20, 0, 0, 1) - case ARLDMI: - return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */ - case ARLDMICC: - return OPVCC(30, 0, 0, 1) | 3<<2 - case ARLDIMI: - return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */ - case ARLDIMICC: - return OPVCC(30, 0, 0, 1) | 3<<2 - case ARLWNM: - return OPVCC(21, 0, 0, 0) /* rlwinm */ - case ARLWNMCC: - return OPVCC(21, 0, 0, 1) - - case ARLDCL: - return OPVCC(30, 0, 0, 0) /* rldicl */ - case ARLDCLCC: - return OPVCC(30, 0, 0, 1) - case ARLDCR: - return OPVCC(30, 1, 0, 0) /* rldicr */ - case ARLDCRCC: - return OPVCC(30, 1, 0, 1) - case ARLDC: - return OPVCC(30, 0, 0, 0) | 2<<2 - case ARLDCCC: - return OPVCC(30, 0, 0, 1) | 2<<2 - - case ASRAW: - return OPVCC(31, 824, 0, 0) - case ASRAWCC: - return OPVCC(31, 824, 0, 1) - case ASRAD: - return OPVCC(31, (413 << 1), 0, 0) - case ASRADCC: - return OPVCC(31, (413 << 1), 0, 1) - - case ASTSW: - return OPVCC(31, 725, 0, 0) - - case ASUBC: - return OPVCC(8, 0, 0, 0) - - case ATW: - return OPVCC(3, 0, 0, 0) - case ATD: - return OPVCC(2, 0, 0, 0) - - /* Vector (VMX/Altivec) instructions */ - /* ISA 2.03 enables these for PPC970. For POWERx processors, these */ - /* are enabled starting at POWER6 (ISA 2.05). */ - case AVSPLTB: - return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */ - case AVSPLTH: - return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */ - case AVSPLTW: - return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */ - - case AVSPLTISB: - return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */ - case AVSPLTISH: - return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */ - case AVSPLTISW: - return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */ - /* End of vector instructions */ - - case AXOR: - return OPVCC(26, 0, 0, 0) /* XORIL */ - case -AXOR: - return OPVCC(27, 0, 0, 0) /* XORIU */ - } - - ctxt.Diag("bad opcode i/r or i/r/r %v", a) - return 0 -} - -/* - * load o(a),d - */ -func opload(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVD: - return OPVCC(58, 0, 0, 0) /* ld */ - case AMOVDU: - return OPVCC(58, 0, 0, 1) /* ldu */ - case AMOVWZ: - return OPVCC(32, 0, 0, 0) /* lwz */ - case AMOVWZU: - return OPVCC(33, 0, 0, 0) /* lwzu */ - case AMOVW: - return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */ - - /* no AMOVWU */ - case AMOVB, AMOVBZ: - return OPVCC(34, 0, 0, 0) - /* load */ - - case AMOVBU, AMOVBZU: - return OPVCC(35, 0, 0, 0) - case AFMOVD: - return OPVCC(50, 0, 0, 0) - case AFMOVDU: - return OPVCC(51, 0, 0, 0) - case AFMOVS: - return OPVCC(48, 0, 0, 0) - case AFMOVSU: - return OPVCC(49, 0, 0, 0) - case AMOVH: - return OPVCC(42, 0, 0, 0) - case AMOVHU: - return OPVCC(43, 0, 0, 0) - case AMOVHZ: - return OPVCC(40, 0, 0, 0) - case AMOVHZU: - return OPVCC(41, 0, 0, 0) - case AMOVMW: - return OPVCC(46, 0, 0, 0) /* lmw */ - } - - ctxt.Diag("bad load opcode %v", a) - return 0 -} - -/* - * indexed load a(b),d - */ -func oploadx(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVWZ: - return OPVCC(31, 23, 0, 0) /* lwzx */ - case AMOVWZU: - return OPVCC(31, 55, 0, 0) /* lwzux */ - case AMOVW: - return OPVCC(31, 341, 0, 0) /* lwax */ - case AMOVWU: - return OPVCC(31, 373, 0, 0) /* lwaux */ - - case AMOVB, AMOVBZ: - return OPVCC(31, 87, 0, 0) /* lbzx */ - - case AMOVBU, AMOVBZU: - return OPVCC(31, 119, 0, 0) /* lbzux */ - case AFMOVD: - return OPVCC(31, 599, 0, 0) /* lfdx */ - case AFMOVDU: - return OPVCC(31, 631, 0, 0) /* lfdux */ - case AFMOVS: - return OPVCC(31, 535, 0, 0) /* lfsx */ - case AFMOVSU: - return OPVCC(31, 567, 0, 0) /* lfsux */ - case AFMOVSX: - return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */ - case AFMOVSZ: - return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */ - case AMOVH: - return OPVCC(31, 343, 0, 0) /* lhax */ - case AMOVHU: - return OPVCC(31, 375, 0, 0) /* lhaux */ - case AMOVHBR: - return OPVCC(31, 790, 0, 0) /* lhbrx */ - case AMOVWBR: - return OPVCC(31, 534, 0, 0) /* lwbrx */ - case AMOVDBR: - return OPVCC(31, 532, 0, 0) /* ldbrx */ - case AMOVHZ: - return OPVCC(31, 279, 0, 0) /* lhzx */ - case AMOVHZU: - return OPVCC(31, 311, 0, 0) /* lhzux */ - case AECIWX: - return OPVCC(31, 310, 0, 0) /* eciwx */ - case ALBAR: - return OPVCC(31, 52, 0, 0) /* lbarx */ - case ALWAR: - return OPVCC(31, 20, 0, 0) /* lwarx */ - case ALDAR: - return OPVCC(31, 84, 0, 0) - case ALSW: - return OPVCC(31, 533, 0, 0) /* lswx */ - case AMOVD: - return OPVCC(31, 21, 0, 0) /* ldx */ - case AMOVDU: - return OPVCC(31, 53, 0, 0) /* ldux */ - - /* Vector (VMX/Altivec) instructions */ - /* ISA 2.03 enables these for PPC970. For POWERx processors, these */ - /* are enabled starting at POWER6 (ISA 2.05). */ - case ALVEBX: - return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */ - case ALVEHX: - return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */ - case ALVEWX: - return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */ - case ALVX: - return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */ - case ALVXL: - return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */ - case ALVSL: - return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */ - case ALVSR: - return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */ - /* End of vector instructions */ - - /* Vector scalar (VSX) instructions */ - /* ISA 2.06 enables these for POWER7. */ - case ALXVD2X: - return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */ - case ALXVDSX: - return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */ - case ALXVW4X: - return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */ - - case ALXSDX: - return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */ - - case ALXSIWAX: - return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */ - case ALXSIWZX: - return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */ - /* End of vector scalar instructions */ - - } - - ctxt.Diag("bad loadx opcode %v", a) - return 0 -} - -/* - * store s,o(d) - */ -func opstore(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVB, AMOVBZ: - return OPVCC(38, 0, 0, 0) /* stb */ - - case AMOVBU, AMOVBZU: - return OPVCC(39, 0, 0, 0) /* stbu */ - case AFMOVD: - return OPVCC(54, 0, 0, 0) /* stfd */ - case AFMOVDU: - return OPVCC(55, 0, 0, 0) /* stfdu */ - case AFMOVS: - return OPVCC(52, 0, 0, 0) /* stfs */ - case AFMOVSU: - return OPVCC(53, 0, 0, 0) /* stfsu */ - - case AMOVHZ, AMOVH: - return OPVCC(44, 0, 0, 0) /* sth */ - - case AMOVHZU, AMOVHU: - return OPVCC(45, 0, 0, 0) /* sthu */ - case AMOVMW: - return OPVCC(47, 0, 0, 0) /* stmw */ - case ASTSW: - return OPVCC(31, 725, 0, 0) /* stswi */ - - case AMOVWZ, AMOVW: - return OPVCC(36, 0, 0, 0) /* stw */ - - case AMOVWZU, AMOVWU: - return OPVCC(37, 0, 0, 0) /* stwu */ - case AMOVD: - return OPVCC(62, 0, 0, 0) /* std */ - case AMOVDU: - return OPVCC(62, 0, 0, 1) /* stdu */ - } - - ctxt.Diag("unknown store opcode %v", a) - return 0 -} - -/* - * indexed store s,a(b) - */ -func opstorex(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case AMOVB, AMOVBZ: - return OPVCC(31, 215, 0, 0) /* stbx */ - - case AMOVBU, AMOVBZU: - return OPVCC(31, 247, 0, 0) /* stbux */ - case AFMOVD: - return OPVCC(31, 727, 0, 0) /* stfdx */ - case AFMOVDU: - return OPVCC(31, 759, 0, 0) /* stfdux */ - case AFMOVS: - return OPVCC(31, 663, 0, 0) /* stfsx */ - case AFMOVSU: - return OPVCC(31, 695, 0, 0) /* stfsux */ - case AFMOVSX: - return OPVCC(31, 983, 0, 0) /* stfiwx */ - - case AMOVHZ, AMOVH: - return OPVCC(31, 407, 0, 0) /* sthx */ - case AMOVHBR: - return OPVCC(31, 918, 0, 0) /* sthbrx */ - - case AMOVHZU, AMOVHU: - return OPVCC(31, 439, 0, 0) /* sthux */ - - case AMOVWZ, AMOVW: - return OPVCC(31, 151, 0, 0) /* stwx */ - - case AMOVWZU, AMOVWU: - return OPVCC(31, 183, 0, 0) /* stwux */ - case ASTSW: - return OPVCC(31, 661, 0, 0) /* stswx */ - case AMOVWBR: - return OPVCC(31, 662, 0, 0) /* stwbrx */ - case ASTBCCC: - return OPVCC(31, 694, 0, 1) /* stbcx. */ - case ASTWCCC: - return OPVCC(31, 150, 0, 1) /* stwcx. */ - case ASTDCCC: - return OPVCC(31, 214, 0, 1) /* stwdx. */ - case AECOWX: - return OPVCC(31, 438, 0, 0) /* ecowx */ - case AMOVD: - return OPVCC(31, 149, 0, 0) /* stdx */ - case AMOVDU: - return OPVCC(31, 181, 0, 0) /* stdux */ - - /* Vector (VMX/Altivec) instructions */ - /* ISA 2.03 enables these for PPC970. For POWERx processors, these */ - /* are enabled starting at POWER6 (ISA 2.05). */ - case ASTVEBX: - return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */ - case ASTVEHX: - return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */ - case ASTVEWX: - return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */ - case ASTVX: - return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */ - case ASTVXL: - return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */ - /* End of vector instructions */ - - /* Vector scalar (VSX) instructions */ - /* ISA 2.06 enables these for POWER7. */ - case ASTXVD2X: - return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */ - case ASTXVW4X: - return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */ - - case ASTXSDX: - return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */ - - case ASTXSIWX: - return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */ - /* End of vector scalar instructions */ - - } - - ctxt.Diag("unknown storex opcode %v", a) - return 0 -} diff --git a/vendor/github.com/google/gops/internal/obj/ppc64/list9.go b/vendor/github.com/google/gops/internal/obj/ppc64/list9.go deleted file mode 100644 index 0ceac09b..00000000 --- a/vendor/github.com/google/gops/internal/obj/ppc64/list9.go +++ /dev/null @@ -1,105 +0,0 @@ -// cmd/9l/list.c from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package ppc64 - -import ( - "fmt" - - "github.com/google/gops/internal/obj" -) - -func init() { - obj.RegisterRegister(obj.RBasePPC64, REG_DCR0+1024, Rconv) - obj.RegisterOpcode(obj.ABasePPC64, Anames) -} - -func Rconv(r int) string { - if r == 0 { - return "NONE" - } - if r == REGG { - // Special case. - return "g" - } - if REG_R0 <= r && r <= REG_R31 { - return fmt.Sprintf("R%d", r-REG_R0) - } - if REG_F0 <= r && r <= REG_F31 { - return fmt.Sprintf("F%d", r-REG_F0) - } - if REG_V0 <= r && r <= REG_V31 { - return fmt.Sprintf("V%d", r-REG_V0) - } - if REG_VS0 <= r && r <= REG_VS63 { - return fmt.Sprintf("VS%d", r-REG_VS0) - } - if REG_CR0 <= r && r <= REG_CR7 { - return fmt.Sprintf("CR%d", r-REG_CR0) - } - if r == REG_CR { - return "CR" - } - if REG_SPR0 <= r && r <= REG_SPR0+1023 { - switch r { - case REG_XER: - return "XER" - - case REG_LR: - return "LR" - - case REG_CTR: - return "CTR" - } - - return fmt.Sprintf("SPR(%d)", r-REG_SPR0) - } - - if REG_DCR0 <= r && r <= REG_DCR0+1023 { - return fmt.Sprintf("DCR(%d)", r-REG_DCR0) - } - if r == REG_FPSCR { - return "FPSCR" - } - if r == REG_MSR { - return "MSR" - } - - return fmt.Sprintf("Rgok(%d)", r-obj.RBasePPC64) -} - -func DRconv(a int) string { - s := "C_??" - if a >= C_NONE && a <= C_NCLASS { - s = cnames9[a] - } - var fp string - fp += s - return fp -} diff --git a/vendor/github.com/google/gops/internal/obj/ppc64/obj9.go b/vendor/github.com/google/gops/internal/obj/ppc64/obj9.go deleted file mode 100644 index 6cff162c..00000000 --- a/vendor/github.com/google/gops/internal/obj/ppc64/obj9.go +++ /dev/null @@ -1,1251 +0,0 @@ -// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package ppc64 - -import ( - "fmt" - "math" - - "github.com/google/gops/internal/obj" - "github.com/google/gops/internal/sys" -) - -func progedit(ctxt *obj.Link, p *obj.Prog) { - p.From.Class = 0 - p.To.Class = 0 - - // Rewrite BR/BL to symbol as TYPE_BRANCH. - switch p.As { - case ABR, - ABL, - obj.ARET, - obj.ADUFFZERO, - obj.ADUFFCOPY: - if p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - } - - // Rewrite float constants to values stored in memory. - switch p.As { - case AFMOVS: - if p.From.Type == obj.TYPE_FCONST { - f32 := float32(p.From.Val.(float64)) - i32 := math.Float32bits(f32) - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 4 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - case AFMOVD: - if p.From.Type == obj.TYPE_FCONST { - i64 := math.Float64bits(p.From.Val.(float64)) - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - // Put >32-bit constants in memory and load them - case AMOVD: - if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset { - literal := fmt.Sprintf("$i64.%016x", uint64(p.From.Offset)) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - } - - // Rewrite SUB constants into ADD. - switch p.As { - case ASUBC: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADDC - } - - case ASUBCCC: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADDCCC - } - - case ASUB: - if p.From.Type == obj.TYPE_CONST { - p.From.Offset = -p.From.Offset - p.As = AADD - } - } - if ctxt.Flag_dynlink { - rewriteToUseGot(ctxt, p) - } -} - -// Rewrite p, if necessary, to access global data via the global offset table. -func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { - if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { - // ADUFFxxx $offset - // becomes - // MOVD runtime.duffxxx@GOT, R12 - // ADD $offset, R12 - // MOVD R12, CTR - // BL (CTR) - var sym *obj.LSym - if p.As == obj.ADUFFZERO { - sym = obj.Linklookup(ctxt, "runtime.duffzero", 0) - } else { - sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0) - } - offset := p.To.Offset - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - p.From.Sym = sym - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R12 - p.To.Name = obj.NAME_NONE - p.To.Offset = 0 - p.To.Sym = nil - p1 := obj.Appendp(ctxt, p) - p1.As = AADD - p1.From.Type = obj.TYPE_CONST - p1.From.Offset = offset - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REG_R12 - p2 := obj.Appendp(ctxt, p1) - p2.As = AMOVD - p2.From.Type = obj.TYPE_REG - p2.From.Reg = REG_R12 - p2.To.Type = obj.TYPE_REG - p2.To.Reg = REG_CTR - p3 := obj.Appendp(ctxt, p2) - p3.As = obj.ACALL - p3.From.Type = obj.TYPE_REG - p3.From.Reg = REG_R12 - p3.To.Type = obj.TYPE_REG - p3.To.Reg = REG_CTR - } - - // We only care about global data: NAME_EXTERN means a global - // symbol in the Go sense, and p.Sym.Local is true for a few - // internally defined symbols. - if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - // MOVD $sym, Rx becomes MOVD sym@GOT, Rx - // MOVD $sym+, Rx becomes MOVD sym@GOT, Rx; ADD , Rx - if p.As != AMOVD { - ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p) - } - if p.To.Type != obj.TYPE_REG { - ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p) - } - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - if p.From.Offset != 0 { - q := obj.Appendp(ctxt, p) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = p.From.Offset - q.To = p.To - p.From.Offset = 0 - } - } - if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - var source *obj.Addr - // MOVx sym, Ry becomes MOVD sym@GOT, REGTMP; MOVx (REGTMP), Ry - // MOVx Ry, sym becomes MOVD sym@GOT, REGTMP; MOVx Ry, (REGTMP) - // An addition may be inserted between the two MOVs if there is an offset. - if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) - } - source = &p.From - } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - source = &p.To - } else { - return - } - if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { - return - } - if source.Sym.Type == obj.STLSBSS { - return - } - if source.Type != obj.TYPE_MEM { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - p1 := obj.Appendp(ctxt, p) - p2 := obj.Appendp(ctxt, p1) - - p1.As = AMOVD - p1.From.Type = obj.TYPE_MEM - p1.From.Sym = source.Sym - p1.From.Name = obj.NAME_GOTREF - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REGTMP - - p2.As = p.As - p2.From = p.From - p2.To = p.To - if p.From.Name == obj.NAME_EXTERN { - p2.From.Reg = REGTMP - p2.From.Name = obj.NAME_NONE - p2.From.Sym = nil - } else if p.To.Name == obj.NAME_EXTERN { - p2.To.Reg = REGTMP - p2.To.Name = obj.NAME_NONE - p2.To.Sym = nil - } else { - return - } - obj.Nopout(p) -} - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - // TODO(minux): add morestack short-cuts with small fixed frame-size. - ctxt.Cursym = cursym - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - p := cursym.Text - textstksiz := p.To.Offset - if textstksiz == -8 { - // Compatibility hack. - p.From3.Offset |= obj.NOFRAME - textstksiz = 0 - } - if textstksiz%8 != 0 { - ctxt.Diag("frame size %d not a multiple of 8", textstksiz) - } - if p.From3.Offset&obj.NOFRAME != 0 { - if textstksiz != 0 { - ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz) - } - } - - cursym.Args = p.To.Val.(int32) - cursym.Locals = int32(textstksiz) - - /* - * find leaf subroutines - * strip NOPs - * expand RET - * expand BECOME pseudo - */ - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f noops\n", obj.Cputime()) - } - - var q *obj.Prog - var q1 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - switch p.As { - /* too hard, just leave alone */ - case obj.ATEXT: - q = p - - p.Mark |= LABEL | LEAF | SYNC - if p.Link != nil { - p.Link.Mark |= LABEL - } - - case ANOR: - q = p - if p.To.Type == obj.TYPE_REG { - if p.To.Reg == REGZERO { - p.Mark |= LABEL | SYNC - } - } - - case ALWAR, - ALBAR, - ASTBCCC, - ASTWCCC, - AECIWX, - AECOWX, - AEIEIO, - AICBI, - AISYNC, - ATLBIE, - ATLBIEL, - ASLBIA, - ASLBIE, - ASLBMFEE, - ASLBMFEV, - ASLBMTE, - ADCBF, - ADCBI, - ADCBST, - ADCBT, - ADCBTST, - ADCBZ, - ASYNC, - ATLBSYNC, - APTESYNC, - ALWSYNC, - ATW, - AWORD, - ARFI, - ARFCI, - ARFID, - AHRFID: - q = p - p.Mark |= LABEL | SYNC - continue - - case AMOVW, AMOVWZ, AMOVD: - q = p - if p.From.Reg >= REG_SPECIAL || p.To.Reg >= REG_SPECIAL { - p.Mark |= LABEL | SYNC - } - continue - - case AFABS, - AFABSCC, - AFADD, - AFADDCC, - AFCTIW, - AFCTIWCC, - AFCTIWZ, - AFCTIWZCC, - AFDIV, - AFDIVCC, - AFMADD, - AFMADDCC, - AFMOVD, - AFMOVDU, - /* case AFMOVDS: */ - AFMOVS, - AFMOVSU, - - /* case AFMOVSD: */ - AFMSUB, - AFMSUBCC, - AFMUL, - AFMULCC, - AFNABS, - AFNABSCC, - AFNEG, - AFNEGCC, - AFNMADD, - AFNMADDCC, - AFNMSUB, - AFNMSUBCC, - AFRSP, - AFRSPCC, - AFSUB, - AFSUBCC: - q = p - - p.Mark |= FLOAT - continue - - case ABL, - ABCL, - obj.ADUFFZERO, - obj.ADUFFCOPY: - cursym.Text.Mark &^= LEAF - fallthrough - - case ABC, - ABEQ, - ABGE, - ABGT, - ABLE, - ABLT, - ABNE, - ABR, - ABVC, - ABVS: - p.Mark |= BRANCH - q = p - q1 = p.Pcond - if q1 != nil { - for q1.As == obj.ANOP { - q1 = q1.Link - p.Pcond = q1 - } - - if q1.Mark&LEAF == 0 { - q1.Mark |= LABEL - } - } else { - p.Mark |= LABEL - } - q1 = p.Link - if q1 != nil { - q1.Mark |= LABEL - } - continue - - case AFCMPO, AFCMPU: - q = p - p.Mark |= FCMP | FLOAT - continue - - case obj.ARET: - q = p - if p.Link != nil { - p.Link.Mark |= LABEL - } - continue - - case obj.ANOP: - q1 = p.Link - q.Link = q1 /* q is non-nop */ - q1.Mark |= p.Mark - continue - - default: - q = p - continue - } - } - - autosize := int32(0) - var p1 *obj.Prog - var p2 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - o := p.As - switch o { - case obj.ATEXT: - autosize = int32(textstksiz) - - if p.Mark&LEAF != 0 && autosize == 0 { - // A leaf function with no locals has no frame. - p.From3.Offset |= obj.NOFRAME - } - - if p.From3.Offset&obj.NOFRAME == 0 { - // If there is a stack frame at all, it includes - // space to save the LR. - autosize += int32(ctxt.FixedFrameSize()) - } - - if p.Mark&LEAF != 0 && autosize < obj.StackSmall { - // A leaf function with a small stack can be marked - // NOSPLIT, avoiding a stack check. - p.From3.Offset |= obj.NOSPLIT - } - - p.To.Offset = int64(autosize) - - q = p - - if ctxt.Flag_shared && cursym.Name != "runtime.duffzero" && cursym.Name != "runtime.duffcopy" && cursym.Name != "runtime.stackBarrier" { - // When compiling Go into PIC, all functions must start - // with instructions to load the TOC pointer into r2: - // - // addis r2, r12, .TOC.-func@ha - // addi r2, r2, .TOC.-func@l+4 - // - // We could probably skip this prologue in some situations - // but it's a bit subtle. However, it is both safe and - // necessary to leave the prologue off duffzero and - // duffcopy as we rely on being able to jump to a specific - // instruction offset for them, and stackBarrier is only - // ever called from an overwritten LR-save slot on the - // stack (when r12 will not be remotely the right thing) - // but fortunately does not access global data. - // - // These are AWORDS because there is no (afaict) way to - // generate the addis instruction except as part of the - // load of a large constant, and in that case there is no - // way to use r12 as the source. - q = obj.Appendp(ctxt, q) - q.As = AWORD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Offset = 0x3c4c0000 - q = obj.Appendp(ctxt, q) - q.As = AWORD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Offset = 0x38420000 - rel := obj.Addrel(ctxt.Cursym) - rel.Off = 0 - rel.Siz = 8 - rel.Sym = obj.Linklookup(ctxt, ".TOC.", 0) - rel.Type = obj.R_ADDRPOWER_PCREL - } - - if cursym.Text.From3.Offset&obj.NOSPLIT == 0 { - q = stacksplit(ctxt, q, autosize) // emit split check - } - - if autosize != 0 { - // Make sure to save link register for non-empty frame, even if - // it is a leaf function, so that traceback works. - if cursym.Text.Mark&LEAF == 0 && autosize >= -BIG && autosize <= BIG { - // Use MOVDU to adjust R1 when saving R31, if autosize is small. - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_LR - q.To.Type = obj.TYPE_REG - q.To.Reg = REGTMP - - q = obj.Appendp(ctxt, q) - q.As = AMOVDU - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REGTMP - q.To.Type = obj.TYPE_MEM - q.To.Offset = int64(-autosize) - q.To.Reg = REGSP - q.Spadj = int32(autosize) - } else { - // Frame size is too large for a MOVDU instruction. - // Store link register before decrementing SP, so if a signal comes - // during the execution of the function prologue, the traceback - // code will not see a half-updated stack frame. - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_LR - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R29 // REGTMP may be used to synthesize large offset in the next instruction - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R29 - q.To.Type = obj.TYPE_MEM - q.To.Offset = int64(-autosize) - q.To.Reg = REGSP - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(-autosize) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = +autosize - } - } else if cursym.Text.Mark&LEAF == 0 { - // A very few functions that do not return to their caller - // (e.g. gogo) are not identified as leaves but still have - // no frame. - cursym.Text.Mark |= LEAF - } - - if cursym.Text.Mark&LEAF != 0 { - cursym.Set(obj.AttrLeaf, true) - break - } - - if ctxt.Flag_shared { - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R2 - q.To.Type = obj.TYPE_MEM - q.To.Reg = REGSP - q.To.Offset = 24 - } - - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOVD g_panic(g), R3 - // CMP R0, R3 - // BEQ end - // MOVD panic_argp(R3), R4 - // ADD $(autosize+8), R1, R5 - // CMP R4, R5 - // BNE end - // ADD $8, R1, R6 - // MOVD R6, panic_argp(R3) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not a ppc64 NOP: it encodes to 0 instruction bytes. - - q = obj.Appendp(ctxt, q) - - q.As = AMOVD - q.From.Type = obj.TYPE_MEM - q.From.Reg = REGG - q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R3 - - q = obj.Appendp(ctxt, q) - q.As = ACMP - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R0 - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R3 - - q = obj.Appendp(ctxt, q) - q.As = ABEQ - q.To.Type = obj.TYPE_BRANCH - p1 = q - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_MEM - q.From.Reg = REG_R3 - q.From.Offset = 0 // Panic.argp - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R4 - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(autosize) + ctxt.FixedFrameSize() - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R5 - - q = obj.Appendp(ctxt, q) - q.As = ACMP - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R4 - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R5 - - q = obj.Appendp(ctxt, q) - q.As = ABNE - q.To.Type = obj.TYPE_BRANCH - p2 = q - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = ctxt.FixedFrameSize() - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R6 - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R6 - q.To.Type = obj.TYPE_MEM - q.To.Reg = REG_R3 - q.To.Offset = 0 // Panic.argp - - q = obj.Appendp(ctxt, q) - - q.As = obj.ANOP - p1.Pcond = q - p2.Pcond = q - } - - case obj.ARET: - if p.From.Type == obj.TYPE_CONST { - ctxt.Diag("using BECOME (%v) is not supported!", p) - break - } - - retTarget := p.To.Sym - - if cursym.Text.Mark&LEAF != 0 { - if autosize == 0 { - p.As = ABR - p.From = obj.Addr{} - if retTarget == nil { - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_LR - } else { - p.To.Type = obj.TYPE_BRANCH - p.To.Sym = retTarget - } - p.Mark |= BRANCH - break - } - - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autosize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REGSP - p.Spadj = -autosize - - q = ctxt.NewProg() - q.As = ABR - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_LR - q.Mark |= BRANCH - q.Spadj = +autosize - - q.Link = p.Link - p.Link = q - break - } - - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Offset = 0 - p.From.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REGTMP - - q = ctxt.NewProg() - q.As = AMOVD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_REG - q.From.Reg = REGTMP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_LR - - q.Link = p.Link - p.Link = q - p = q - - if false { - // Debug bad returns - q = ctxt.NewProg() - - q.As = AMOVD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_MEM - q.From.Offset = 0 - q.From.Reg = REGTMP - q.To.Type = obj.TYPE_REG - q.To.Reg = REGTMP - - q.Link = p.Link - p.Link = q - p = q - } - - if autosize != 0 { - q = ctxt.NewProg() - q.As = AADD - q.Lineno = p.Lineno - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(autosize) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = -autosize - - q.Link = p.Link - p.Link = q - } - - q1 = ctxt.NewProg() - q1.As = ABR - q1.Lineno = p.Lineno - if retTarget == nil { - q1.To.Type = obj.TYPE_REG - q1.To.Reg = REG_LR - } else { - q1.To.Type = obj.TYPE_BRANCH - q1.To.Sym = retTarget - } - q1.Mark |= BRANCH - q1.Spadj = +autosize - - q1.Link = q.Link - q.Link = q1 - case AADD: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST { - p.Spadj = int32(-p.From.Offset) - } - } - } -} - -/* -// instruction scheduling - if(debug['Q'] == 0) - return; - - curtext = nil; - q = nil; // p - 1 - q1 = firstp; // top of block - o = 0; // count of instructions - for(p = firstp; p != nil; p = p1) { - p1 = p->link; - o++; - if(p->mark & NOSCHED){ - if(q1 != p){ - sched(q1, q); - } - for(; p != nil; p = p->link){ - if(!(p->mark & NOSCHED)) - break; - q = p; - } - p1 = p; - q1 = p; - o = 0; - continue; - } - if(p->mark & (LABEL|SYNC)) { - if(q1 != p) - sched(q1, q); - q1 = p; - o = 1; - } - if(p->mark & (BRANCH|SYNC)) { - sched(q1, p); - q1 = p1; - o = 0; - } - if(o >= NSCHED) { - sched(q1, p); - q1 = p1; - o = 0; - } - q = p; - } -*/ -func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { - p0 := p // save entry point, but skipping the two instructions setting R2 in shared mode - - // MOVD g_stackguard(g), R3 - p = obj.Appendp(ctxt, p) - - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - - var q *obj.Prog - if framesize <= obj.StackSmall { - // small stack: SP < stackguard - // CMP stackguard, SP - p = obj.Appendp(ctxt, p) - - p.As = ACMPU - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.To.Type = obj.TYPE_REG - p.To.Reg = REGSP - } else if framesize <= obj.StackBig { - // large stack: SP-framesize < stackguard-StackSmall - // ADD $-framesize, SP, R4 - // CMP stackguard, R4 - p = obj.Appendp(ctxt, p) - - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(-framesize) - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.As = ACMPU - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - } else { - // Such a large stack we need to protect against wraparound. - // If SP is close to zero: - // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // - // Preemption sets stackguard to StackPreempt, a very large value. - // That breaks the math above, so we have to check for that explicitly. - // // stackguard is R3 - // CMP R3, $StackPreempt - // BEQ label-of-call-to-morestack - // ADD $StackGuard, SP, R4 - // SUB R3, R4 - // MOVD $(framesize+(StackGuard-StackSmall)), R31 - // CMPU R31, R4 - p = obj.Appendp(ctxt, p) - - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.To.Type = obj.TYPE_CONST - p.To.Offset = obj.StackPreempt - - p = obj.Appendp(ctxt, p) - q = p - p.As = ABEQ - p.To.Type = obj.TYPE_BRANCH - - p = obj.Appendp(ctxt, p) - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = obj.StackGuard - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.As = ASUB - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall - p.To.Type = obj.TYPE_REG - p.To.Reg = REGTMP - - p = obj.Appendp(ctxt, p) - p.As = ACMPU - p.From.Type = obj.TYPE_REG - p.From.Reg = REGTMP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - } - - // q1: BLT done - p = obj.Appendp(ctxt, p) - q1 := p - - p.As = ABLT - p.To.Type = obj.TYPE_BRANCH - - // MOVD LR, R5 - p = obj.Appendp(ctxt, p) - - p.As = AMOVD - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_LR - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R5 - if q != nil { - q.Pcond = p - } - - var morestacksym *obj.LSym - if ctxt.Cursym.CFunc() { - morestacksym = obj.Linklookup(ctxt, "runtime.morestackc", 0) - } else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { - morestacksym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0) - } else { - morestacksym = obj.Linklookup(ctxt, "runtime.morestack", 0) - } - - if ctxt.Flag_shared { - // In PPC64 PIC code, R2 is used as TOC pointer derived from R12 - // which is the address of function entry point when entering - // the function. We need to preserve R2 across call to morestack. - // Fortunately, in shared mode, 8(SP) and 16(SP) are reserved in - // the caller's frame, but not used (0(SP) is caller's saved LR, - // 24(SP) is caller's saved R2). Use 8(SP) to save this function's R2. - - // MOVD R12, 8(SP) - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R2 - p.To.Type = obj.TYPE_MEM - p.To.Reg = REGSP - p.To.Offset = 8 - } - - if ctxt.Flag_dynlink { - // Avoid calling morestack via a PLT when dynamically linking. The - // PLT stubs generated by the system linker on ppc64le when "std r2, - // 24(r1)" to save the TOC pointer in their callers stack - // frame. Unfortunately (and necessarily) morestack is called before - // the function that calls it sets up its frame and so the PLT ends - // up smashing the saved TOC pointer for its caller's caller. - // - // According to the ABI documentation there is a mechanism to avoid - // the TOC save that the PLT stub does (put a R_PPC64_TOCSAVE - // relocation on the nop after the call to morestack) but at the time - // of writing it is not supported at all by gold and my attempt to - // use it with ld.bfd caused an internal linker error. So this hack - // seems preferable. - - // MOVD $runtime.morestack(SB), R12 - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Sym = morestacksym - p.From.Name = obj.NAME_GOTREF - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R12 - - // MOVD R12, CTR - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R12 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_CTR - - // BL CTR - p = obj.Appendp(ctxt, p) - p.As = obj.ACALL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R12 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_CTR - } else { - // BL runtime.morestack(SB) - p = obj.Appendp(ctxt, p) - - p.As = ABL - p.To.Type = obj.TYPE_BRANCH - p.To.Sym = morestacksym - } - - if ctxt.Flag_shared { - // MOVD 8(SP), R2 - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGSP - p.From.Offset = 8 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - } - - // BR start - p = obj.Appendp(ctxt, p) - p.As = ABR - p.To.Type = obj.TYPE_BRANCH - p.Pcond = p0.Link - - // placeholder for q1's jump target - p = obj.Appendp(ctxt, p) - - p.As = obj.ANOP // zero-width place holder - q1.Pcond = p - - return p -} - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func relinv(a obj.As) obj.As { - switch a { - case ABEQ: - return ABNE - case ABNE: - return ABEQ - - case ABGE: - return ABLT - case ABLT: - return ABGE - - case ABGT: - return ABLE - case ABLE: - return ABGT - - case ABVC: - return ABVS - case ABVS: - return ABVC - } - - return 0 -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var r *obj.Prog - var b obj.As - var i int - -loop: - if p == nil { - return - } - a := p.As - if a == ABR { - q = p.Pcond - if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) { - p.Mark |= FOLL - (*last).Link = p - *last = p - p = p.Link - xfol(ctxt, p, last) - p = q - if p != nil && p.Mark&FOLL == 0 { - goto loop - } - return - } - - if q != nil { - p.Mark |= FOLL - p = q - if p.Mark&FOLL == 0 { - goto loop - } - } - } - - if p.Mark&FOLL != 0 { - i = 0 - q = p - for ; i < 4; i, q = i+1, q.Link { - if q == *last || (q.Mark&NOSCHED != 0) { - break - } - b = 0 /* set */ - a = q.As - if a == obj.ANOP { - i-- - continue - } - - if a == ABR || a == obj.ARET || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID { - goto copy - } - if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { - continue - } - b = relinv(a) - if b == 0 { - continue - } - - copy: - for { - r = ctxt.NewProg() - *r = *p - if r.Mark&FOLL == 0 { - fmt.Printf("can't happen 1\n") - } - r.Mark |= FOLL - if p != q { - p = p.Link - (*last).Link = r - *last = r - continue - } - - (*last).Link = r - *last = r - if a == ABR || a == obj.ARET || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID { - return - } - r.As = b - r.Pcond = p.Link - r.Link = p.Pcond - if r.Link.Mark&FOLL == 0 { - xfol(ctxt, r.Link, last) - } - if r.Pcond.Mark&FOLL == 0 { - fmt.Printf("can't happen 2\n") - } - return - } - } - - a = ABR - q = ctxt.NewProg() - q.As = a - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - p.Mark |= FOLL - (*last).Link = p - *last = p - if a == ABR || a == obj.ARET || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID { - if p.Mark&NOSCHED != 0 { - p = p.Link - goto loop - } - - return - } - - if p.Pcond != nil { - if a != ABL && p.Link != nil { - xfol(ctxt, p.Link, last) - p = p.Pcond - if p == nil || (p.Mark&FOLL != 0) { - return - } - goto loop - } - } - - p = p.Link - goto loop -} - -var Linkppc64 = obj.LinkArch{ - Arch: sys.ArchPPC64, - Preprocess: preprocess, - Assemble: span9, - Follow: follow, - Progedit: progedit, -} - -var Linkppc64le = obj.LinkArch{ - Arch: sys.ArchPPC64LE, - Preprocess: preprocess, - Assemble: span9, - Follow: follow, - Progedit: progedit, -} diff --git a/vendor/github.com/google/gops/internal/obj/reloctype_string.go b/vendor/github.com/google/gops/internal/obj/reloctype_string.go deleted file mode 100644 index 6de617cd..00000000 --- a/vendor/github.com/google/gops/internal/obj/reloctype_string.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated by "stringer -type=RelocType"; DO NOT EDIT - -package obj - -import "fmt" - -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLS" - -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 195, 206, 216, 225, 235, 249, 263, 279, 293, 307, 318, 332, 347, 364, 382, 403, 413, 424, 437} - -func (i RelocType) String() string { - i -= 1 - if i < 0 || i >= RelocType(len(_RelocType_index)-1) { - return fmt.Sprintf("RelocType(%d)", i+1) - } - return _RelocType_name[_RelocType_index[i]:_RelocType_index[i+1]] -} diff --git a/vendor/github.com/google/gops/internal/obj/s390x/a.out.go b/vendor/github.com/google/gops/internal/obj/s390x/a.out.go deleted file mode 100644 index df7192f3..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/a.out.go +++ /dev/null @@ -1,926 +0,0 @@ -// Based on cmd/internal/obj/ppc64/a.out.go. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package s390x - -import "github.com/google/gops/internal/obj" - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p s390x - -const ( - NSNAME = 8 - NSYM = 50 - NREG = 16 // number of general purpose registers - NFREG = 16 // number of floating point registers -) - -const ( - // General purpose registers (GPRs). - REG_R0 = obj.RBaseS390X + iota - REG_R1 - REG_R2 - REG_R3 - REG_R4 - REG_R5 - REG_R6 - REG_R7 - REG_R8 - REG_R9 - REG_R10 - REG_R11 - REG_R12 - REG_R13 - REG_R14 - REG_R15 - - // Floating point registers (FPRs). - REG_F0 - REG_F1 - REG_F2 - REG_F3 - REG_F4 - REG_F5 - REG_F6 - REG_F7 - REG_F8 - REG_F9 - REG_F10 - REG_F11 - REG_F12 - REG_F13 - REG_F14 - REG_F15 - - // Vector registers (VRs) - only available when the vector - // facility is installed. - // V0-V15 are aliases for F0-F15. - // We keep them in a separate space to make printing etc. easier - // If the code generator ever emits vector instructions it will - // need to take into account the aliasing. - REG_V0 - REG_V1 - REG_V2 - REG_V3 - REG_V4 - REG_V5 - REG_V6 - REG_V7 - REG_V8 - REG_V9 - REG_V10 - REG_V11 - REG_V12 - REG_V13 - REG_V14 - REG_V15 - REG_V16 - REG_V17 - REG_V18 - REG_V19 - REG_V20 - REG_V21 - REG_V22 - REG_V23 - REG_V24 - REG_V25 - REG_V26 - REG_V27 - REG_V28 - REG_V29 - REG_V30 - REG_V31 - - // Access registers (ARs). - // The thread pointer is typically stored in the register pair - // AR0 and AR1. - REG_AR0 - REG_AR1 - REG_AR2 - REG_AR3 - REG_AR4 - REG_AR5 - REG_AR6 - REG_AR7 - REG_AR8 - REG_AR9 - REG_AR10 - REG_AR11 - REG_AR12 - REG_AR13 - REG_AR14 - REG_AR15 - - REG_RESERVED // end of allocated registers - - REGZERO = REG_R0 // set to zero - REGARG = -1 // -1 disables passing the first argument in register - REGRT1 = REG_R3 // used during zeroing of the stack - not reserved - REGRT2 = REG_R4 // used during zeroing of the stack - not reserved - REGTMP = REG_R10 // scratch register used in the assembler and linker - REGTMP2 = REG_R11 // scratch register used in the assembler and linker - REGCTXT = REG_R12 // context for closures - REGG = REG_R13 // G - REG_LR = REG_R14 // link register - REGSP = REG_R15 // stack pointer -) - -const ( - BIG = 32768 - 8 - DISP12 = 4096 - DISP16 = 65536 - DISP20 = 1048576 -) - -const ( - // mark flags - LABEL = 1 << 0 - LEAF = 1 << 1 - FLOAT = 1 << 2 - BRANCH = 1 << 3 - LOAD = 1 << 4 - FCMP = 1 << 5 - SYNC = 1 << 6 - LIST = 1 << 7 - FOLL = 1 << 8 - NOSCHED = 1 << 9 -) - -const ( // comments from func aclass in asmz.go - C_NONE = iota - C_REG // general-purpose register (64-bit) - C_FREG // floating-point register (64-bit) - C_VREG // vector register (128-bit) - C_AREG // access register (32-bit) - C_ZCON // constant == 0 - C_SCON // 0 <= constant <= 0x7fff (positive int16) - C_UCON // constant & 0xffff == 0 (int16 or uint16) - C_ADDCON // 0 > constant >= -0x8000 (negative int16) - C_ANDCON // constant <= 0xffff - C_LCON // constant (int32 or uint32) - C_DCON // constant (int64 or uint64) - C_SACON // computed address, 16-bit displacement, possibly SP-relative - C_LACON // computed address, 32-bit displacement, possibly SP-relative - C_DACON // computed address, 64-bit displacment? - C_SBRA // short branch - C_LBRA // long branch - C_SAUTO // short auto - C_LAUTO // long auto - C_ZOREG // heap address, register-based, displacement == 0 - C_SOREG // heap address, register-based, int16 displacement - C_LOREG // heap address, register-based, int32 displacement - C_TLS_LE // TLS - local exec model (for executables) - C_TLS_IE // TLS - initial exec model (for shared libraries loaded at program startup) - C_GOK // general address - C_ADDR // relocation for extern or static symbols (loads and stores) - C_SYMADDR // relocation for extern or static symbols (address taking) - C_GOTADDR // GOT slot for a symbol in -dynlink mode - C_TEXTSIZE // text size - C_ANY - C_NCLASS // must be the last -) - -const ( - // integer arithmetic - AADD = obj.ABaseS390X + obj.A_ARCHSPECIFIC + iota - AADDC - AADDE - AADDW - ADIVW - ADIVWU - ADIVD - ADIVDU - AMODW - AMODWU - AMODD - AMODDU - AMULLW - AMULLD - AMULHD - AMULHDU - ASUB - ASUBC - ASUBV - ASUBE - ASUBW - ANEG - ANEGW - - // integer moves - AMOVWBR - AMOVB - AMOVBZ - AMOVH - AMOVHBR - AMOVHZ - AMOVW - AMOVWZ - AMOVD - AMOVDBR - - // conditional moves - AMOVDEQ - AMOVDGE - AMOVDGT - AMOVDLE - AMOVDLT - AMOVDNE - - // find leftmost one - AFLOGR - - // integer bitwise - AAND - AANDW - AOR - AORW - AXOR - AXORW - ASLW - ASLD - ASRW - ASRAW - ASRD - ASRAD - ARLL - ARLLG - - // floating point - AFABS - AFADD - AFADDS - AFCMPO - AFCMPU - ACEBR - AFDIV - AFDIVS - AFMADD - AFMADDS - AFMOVD - AFMOVS - AFMSUB - AFMSUBS - AFMUL - AFMULS - AFNABS - AFNEG - AFNEGS - AFNMADD - AFNMADDS - AFNMSUB - AFNMSUBS - ALEDBR - ALDEBR - AFSUB - AFSUBS - AFSQRT - AFSQRTS - AFIEBR - AFIDBR - - // convert from int32/int64 to float/float64 - ACEFBRA - ACDFBRA - ACEGBRA - ACDGBRA - - // convert from float/float64 to int32/int64 - ACFEBRA - ACFDBRA - ACGEBRA - ACGDBRA - - // convert from uint32/uint64 to float/float64 - ACELFBR - ACDLFBR - ACELGBR - ACDLGBR - - // convert from float/float64 to uint32/uint64 - ACLFEBR - ACLFDBR - ACLGEBR - ACLGDBR - - // compare - ACMP - ACMPU - ACMPW - ACMPWU - - // compare and swap - ACS - ACSG - - // serialize - ASYNC - - // branch - ABC - ABCL - ABEQ - ABGE - ABGT - ABLE - ABLT - ABLEU - ABLTU - ABNE - ABVC - ABVS - ASYSCALL - - // compare and branch - ACMPBEQ - ACMPBGE - ACMPBGT - ACMPBLE - ACMPBLT - ACMPBNE - ACMPUBEQ - ACMPUBGE - ACMPUBGT - ACMPUBLE - ACMPUBLT - ACMPUBNE - - // storage-and-storage - AMVC - ACLC - AXC - AOC - ANC - - // load - AEXRL - ALARL - ALA - ALAY - - // interlocked load and op - ALAA - ALAAG - ALAAL - ALAALG - ALAN - ALANG - ALAX - ALAXG - ALAO - ALAOG - - // load/store multiple - ALMY - ALMG - ASTMY - ASTMG - - // store clock - ASTCK - ASTCKC - ASTCKE - ASTCKF - - // macros - ACLEAR - - // vector - AVA - AVAB - AVAH - AVAF - AVAG - AVAQ - AVACC - AVACCB - AVACCH - AVACCF - AVACCG - AVACCQ - AVAC - AVACQ - AVACCC - AVACCCQ - AVN - AVNC - AVAVG - AVAVGB - AVAVGH - AVAVGF - AVAVGG - AVAVGL - AVAVGLB - AVAVGLH - AVAVGLF - AVAVGLG - AVCKSM - AVCEQ - AVCEQB - AVCEQH - AVCEQF - AVCEQG - AVCEQBS - AVCEQHS - AVCEQFS - AVCEQGS - AVCH - AVCHB - AVCHH - AVCHF - AVCHG - AVCHBS - AVCHHS - AVCHFS - AVCHGS - AVCHL - AVCHLB - AVCHLH - AVCHLF - AVCHLG - AVCHLBS - AVCHLHS - AVCHLFS - AVCHLGS - AVCLZ - AVCLZB - AVCLZH - AVCLZF - AVCLZG - AVCTZ - AVCTZB - AVCTZH - AVCTZF - AVCTZG - AVEC - AVECB - AVECH - AVECF - AVECG - AVECL - AVECLB - AVECLH - AVECLF - AVECLG - AVERIM - AVERIMB - AVERIMH - AVERIMF - AVERIMG - AVERLL - AVERLLB - AVERLLH - AVERLLF - AVERLLG - AVERLLV - AVERLLVB - AVERLLVH - AVERLLVF - AVERLLVG - AVESLV - AVESLVB - AVESLVH - AVESLVF - AVESLVG - AVESL - AVESLB - AVESLH - AVESLF - AVESLG - AVESRA - AVESRAB - AVESRAH - AVESRAF - AVESRAG - AVESRAV - AVESRAVB - AVESRAVH - AVESRAVF - AVESRAVG - AVESRL - AVESRLB - AVESRLH - AVESRLF - AVESRLG - AVESRLV - AVESRLVB - AVESRLVH - AVESRLVF - AVESRLVG - AVX - AVFAE - AVFAEB - AVFAEH - AVFAEF - AVFAEBS - AVFAEHS - AVFAEFS - AVFAEZB - AVFAEZH - AVFAEZF - AVFAEZBS - AVFAEZHS - AVFAEZFS - AVFEE - AVFEEB - AVFEEH - AVFEEF - AVFEEBS - AVFEEHS - AVFEEFS - AVFEEZB - AVFEEZH - AVFEEZF - AVFEEZBS - AVFEEZHS - AVFEEZFS - AVFENE - AVFENEB - AVFENEH - AVFENEF - AVFENEBS - AVFENEHS - AVFENEFS - AVFENEZB - AVFENEZH - AVFENEZF - AVFENEZBS - AVFENEZHS - AVFENEZFS - AVFA - AVFADB - AWFADB - AWFK - AWFKDB - AVFCE - AVFCEDB - AVFCEDBS - AWFCEDB - AWFCEDBS - AVFCH - AVFCHDB - AVFCHDBS - AWFCHDB - AWFCHDBS - AVFCHE - AVFCHEDB - AVFCHEDBS - AWFCHEDB - AWFCHEDBS - AWFC - AWFCDB - AVCDG - AVCDGB - AWCDGB - AVCDLG - AVCDLGB - AWCDLGB - AVCGD - AVCGDB - AWCGDB - AVCLGD - AVCLGDB - AWCLGDB - AVFD - AVFDDB - AWFDDB - AVLDE - AVLDEB - AWLDEB - AVLED - AVLEDB - AWLEDB - AVFM - AVFMDB - AWFMDB - AVFMA - AVFMADB - AWFMADB - AVFMS - AVFMSDB - AWFMSDB - AVFPSO - AVFPSODB - AWFPSODB - AVFLCDB - AWFLCDB - AVFLNDB - AWFLNDB - AVFLPDB - AWFLPDB - AVFSQ - AVFSQDB - AWFSQDB - AVFS - AVFSDB - AWFSDB - AVFTCI - AVFTCIDB - AWFTCIDB - AVGFM - AVGFMB - AVGFMH - AVGFMF - AVGFMG - AVGFMA - AVGFMAB - AVGFMAH - AVGFMAF - AVGFMAG - AVGEF - AVGEG - AVGBM - AVZERO - AVONE - AVGM - AVGMB - AVGMH - AVGMF - AVGMG - AVISTR - AVISTRB - AVISTRH - AVISTRF - AVISTRBS - AVISTRHS - AVISTRFS - AVL - AVLR - AVLREP - AVLREPB - AVLREPH - AVLREPF - AVLREPG - AVLC - AVLCB - AVLCH - AVLCF - AVLCG - AVLEH - AVLEF - AVLEG - AVLEB - AVLEIH - AVLEIF - AVLEIG - AVLEIB - AVFI - AVFIDB - AWFIDB - AVLGV - AVLGVB - AVLGVH - AVLGVF - AVLGVG - AVLLEZ - AVLLEZB - AVLLEZH - AVLLEZF - AVLLEZG - AVLM - AVLP - AVLPB - AVLPH - AVLPF - AVLPG - AVLBB - AVLVG - AVLVGB - AVLVGH - AVLVGF - AVLVGG - AVLVGP - AVLL - AVMX - AVMXB - AVMXH - AVMXF - AVMXG - AVMXL - AVMXLB - AVMXLH - AVMXLF - AVMXLG - AVMRH - AVMRHB - AVMRHH - AVMRHF - AVMRHG - AVMRL - AVMRLB - AVMRLH - AVMRLF - AVMRLG - AVMN - AVMNB - AVMNH - AVMNF - AVMNG - AVMNL - AVMNLB - AVMNLH - AVMNLF - AVMNLG - AVMAE - AVMAEB - AVMAEH - AVMAEF - AVMAH - AVMAHB - AVMAHH - AVMAHF - AVMALE - AVMALEB - AVMALEH - AVMALEF - AVMALH - AVMALHB - AVMALHH - AVMALHF - AVMALO - AVMALOB - AVMALOH - AVMALOF - AVMAL - AVMALB - AVMALHW - AVMALF - AVMAO - AVMAOB - AVMAOH - AVMAOF - AVME - AVMEB - AVMEH - AVMEF - AVMH - AVMHB - AVMHH - AVMHF - AVMLE - AVMLEB - AVMLEH - AVMLEF - AVMLH - AVMLHB - AVMLHH - AVMLHF - AVMLO - AVMLOB - AVMLOH - AVMLOF - AVML - AVMLB - AVMLHW - AVMLF - AVMO - AVMOB - AVMOH - AVMOF - AVNO - AVNOT - AVO - AVPK - AVPKH - AVPKF - AVPKG - AVPKLS - AVPKLSH - AVPKLSF - AVPKLSG - AVPKLSHS - AVPKLSFS - AVPKLSGS - AVPKS - AVPKSH - AVPKSF - AVPKSG - AVPKSHS - AVPKSFS - AVPKSGS - AVPERM - AVPDI - AVPOPCT - AVREP - AVREPB - AVREPH - AVREPF - AVREPG - AVREPI - AVREPIB - AVREPIH - AVREPIF - AVREPIG - AVSCEF - AVSCEG - AVSEL - AVSL - AVSLB - AVSLDB - AVSRA - AVSRAB - AVSRL - AVSRLB - AVSEG - AVSEGB - AVSEGH - AVSEGF - AVST - AVSTEH - AVSTEF - AVSTEG - AVSTEB - AVSTM - AVSTL - AVSTRC - AVSTRCB - AVSTRCH - AVSTRCF - AVSTRCBS - AVSTRCHS - AVSTRCFS - AVSTRCZB - AVSTRCZH - AVSTRCZF - AVSTRCZBS - AVSTRCZHS - AVSTRCZFS - AVS - AVSB - AVSH - AVSF - AVSG - AVSQ - AVSCBI - AVSCBIB - AVSCBIH - AVSCBIF - AVSCBIG - AVSCBIQ - AVSBCBI - AVSBCBIQ - AVSBI - AVSBIQ - AVSUMG - AVSUMGH - AVSUMGF - AVSUMQ - AVSUMQF - AVSUMQG - AVSUM - AVSUMB - AVSUMH - AVTM - AVUPH - AVUPHB - AVUPHH - AVUPHF - AVUPLH - AVUPLHB - AVUPLHH - AVUPLHF - AVUPLL - AVUPLLB - AVUPLLH - AVUPLLF - AVUPL - AVUPLB - AVUPLHW - AVUPLF - - // binary - ABYTE - AWORD - ADWORD - - // end marker - ALAST - - // aliases - ABR = obj.AJMP - ABL = obj.ACALL -) diff --git a/vendor/github.com/google/gops/internal/obj/s390x/anames.go b/vendor/github.com/google/gops/internal/obj/s390x/anames.go deleted file mode 100644 index b7e49e2d..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/anames.go +++ /dev/null @@ -1,675 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p s390x -// Do not edit. - -package s390x - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "ADD", - "ADDC", - "ADDE", - "ADDW", - "DIVW", - "DIVWU", - "DIVD", - "DIVDU", - "MODW", - "MODWU", - "MODD", - "MODDU", - "MULLW", - "MULLD", - "MULHD", - "MULHDU", - "SUB", - "SUBC", - "SUBV", - "SUBE", - "SUBW", - "NEG", - "NEGW", - "MOVWBR", - "MOVB", - "MOVBZ", - "MOVH", - "MOVHBR", - "MOVHZ", - "MOVW", - "MOVWZ", - "MOVD", - "MOVDBR", - "MOVDEQ", - "MOVDGE", - "MOVDGT", - "MOVDLE", - "MOVDLT", - "MOVDNE", - "FLOGR", - "AND", - "ANDW", - "OR", - "ORW", - "XOR", - "XORW", - "SLW", - "SLD", - "SRW", - "SRAW", - "SRD", - "SRAD", - "RLL", - "RLLG", - "FABS", - "FADD", - "FADDS", - "FCMPO", - "FCMPU", - "CEBR", - "FDIV", - "FDIVS", - "FMADD", - "FMADDS", - "FMOVD", - "FMOVS", - "FMSUB", - "FMSUBS", - "FMUL", - "FMULS", - "FNABS", - "FNEG", - "FNEGS", - "FNMADD", - "FNMADDS", - "FNMSUB", - "FNMSUBS", - "LEDBR", - "LDEBR", - "FSUB", - "FSUBS", - "FSQRT", - "FSQRTS", - "FIEBR", - "FIDBR", - "CEFBRA", - "CDFBRA", - "CEGBRA", - "CDGBRA", - "CFEBRA", - "CFDBRA", - "CGEBRA", - "CGDBRA", - "CELFBR", - "CDLFBR", - "CELGBR", - "CDLGBR", - "CLFEBR", - "CLFDBR", - "CLGEBR", - "CLGDBR", - "CMP", - "CMPU", - "CMPW", - "CMPWU", - "CS", - "CSG", - "SYNC", - "BC", - "BCL", - "BEQ", - "BGE", - "BGT", - "BLE", - "BLT", - "BLEU", - "BLTU", - "BNE", - "BVC", - "BVS", - "SYSCALL", - "CMPBEQ", - "CMPBGE", - "CMPBGT", - "CMPBLE", - "CMPBLT", - "CMPBNE", - "CMPUBEQ", - "CMPUBGE", - "CMPUBGT", - "CMPUBLE", - "CMPUBLT", - "CMPUBNE", - "MVC", - "CLC", - "XC", - "OC", - "NC", - "EXRL", - "LARL", - "LA", - "LAY", - "LAA", - "LAAG", - "LAAL", - "LAALG", - "LAN", - "LANG", - "LAX", - "LAXG", - "LAO", - "LAOG", - "LMY", - "LMG", - "STMY", - "STMG", - "STCK", - "STCKC", - "STCKE", - "STCKF", - "CLEAR", - "VA", - "VAB", - "VAH", - "VAF", - "VAG", - "VAQ", - "VACC", - "VACCB", - "VACCH", - "VACCF", - "VACCG", - "VACCQ", - "VAC", - "VACQ", - "VACCC", - "VACCCQ", - "VN", - "VNC", - "VAVG", - "VAVGB", - "VAVGH", - "VAVGF", - "VAVGG", - "VAVGL", - "VAVGLB", - "VAVGLH", - "VAVGLF", - "VAVGLG", - "VCKSM", - "VCEQ", - "VCEQB", - "VCEQH", - "VCEQF", - "VCEQG", - "VCEQBS", - "VCEQHS", - "VCEQFS", - "VCEQGS", - "VCH", - "VCHB", - "VCHH", - "VCHF", - "VCHG", - "VCHBS", - "VCHHS", - "VCHFS", - "VCHGS", - "VCHL", - "VCHLB", - "VCHLH", - "VCHLF", - "VCHLG", - "VCHLBS", - "VCHLHS", - "VCHLFS", - "VCHLGS", - "VCLZ", - "VCLZB", - "VCLZH", - "VCLZF", - "VCLZG", - "VCTZ", - "VCTZB", - "VCTZH", - "VCTZF", - "VCTZG", - "VEC", - "VECB", - "VECH", - "VECF", - "VECG", - "VECL", - "VECLB", - "VECLH", - "VECLF", - "VECLG", - "VERIM", - "VERIMB", - "VERIMH", - "VERIMF", - "VERIMG", - "VERLL", - "VERLLB", - "VERLLH", - "VERLLF", - "VERLLG", - "VERLLV", - "VERLLVB", - "VERLLVH", - "VERLLVF", - "VERLLVG", - "VESLV", - "VESLVB", - "VESLVH", - "VESLVF", - "VESLVG", - "VESL", - "VESLB", - "VESLH", - "VESLF", - "VESLG", - "VESRA", - "VESRAB", - "VESRAH", - "VESRAF", - "VESRAG", - "VESRAV", - "VESRAVB", - "VESRAVH", - "VESRAVF", - "VESRAVG", - "VESRL", - "VESRLB", - "VESRLH", - "VESRLF", - "VESRLG", - "VESRLV", - "VESRLVB", - "VESRLVH", - "VESRLVF", - "VESRLVG", - "VX", - "VFAE", - "VFAEB", - "VFAEH", - "VFAEF", - "VFAEBS", - "VFAEHS", - "VFAEFS", - "VFAEZB", - "VFAEZH", - "VFAEZF", - "VFAEZBS", - "VFAEZHS", - "VFAEZFS", - "VFEE", - "VFEEB", - "VFEEH", - "VFEEF", - "VFEEBS", - "VFEEHS", - "VFEEFS", - "VFEEZB", - "VFEEZH", - "VFEEZF", - "VFEEZBS", - "VFEEZHS", - "VFEEZFS", - "VFENE", - "VFENEB", - "VFENEH", - "VFENEF", - "VFENEBS", - "VFENEHS", - "VFENEFS", - "VFENEZB", - "VFENEZH", - "VFENEZF", - "VFENEZBS", - "VFENEZHS", - "VFENEZFS", - "VFA", - "VFADB", - "WFADB", - "WFK", - "WFKDB", - "VFCE", - "VFCEDB", - "VFCEDBS", - "WFCEDB", - "WFCEDBS", - "VFCH", - "VFCHDB", - "VFCHDBS", - "WFCHDB", - "WFCHDBS", - "VFCHE", - "VFCHEDB", - "VFCHEDBS", - "WFCHEDB", - "WFCHEDBS", - "WFC", - "WFCDB", - "VCDG", - "VCDGB", - "WCDGB", - "VCDLG", - "VCDLGB", - "WCDLGB", - "VCGD", - "VCGDB", - "WCGDB", - "VCLGD", - "VCLGDB", - "WCLGDB", - "VFD", - "VFDDB", - "WFDDB", - "VLDE", - "VLDEB", - "WLDEB", - "VLED", - "VLEDB", - "WLEDB", - "VFM", - "VFMDB", - "WFMDB", - "VFMA", - "VFMADB", - "WFMADB", - "VFMS", - "VFMSDB", - "WFMSDB", - "VFPSO", - "VFPSODB", - "WFPSODB", - "VFLCDB", - "WFLCDB", - "VFLNDB", - "WFLNDB", - "VFLPDB", - "WFLPDB", - "VFSQ", - "VFSQDB", - "WFSQDB", - "VFS", - "VFSDB", - "WFSDB", - "VFTCI", - "VFTCIDB", - "WFTCIDB", - "VGFM", - "VGFMB", - "VGFMH", - "VGFMF", - "VGFMG", - "VGFMA", - "VGFMAB", - "VGFMAH", - "VGFMAF", - "VGFMAG", - "VGEF", - "VGEG", - "VGBM", - "VZERO", - "VONE", - "VGM", - "VGMB", - "VGMH", - "VGMF", - "VGMG", - "VISTR", - "VISTRB", - "VISTRH", - "VISTRF", - "VISTRBS", - "VISTRHS", - "VISTRFS", - "VL", - "VLR", - "VLREP", - "VLREPB", - "VLREPH", - "VLREPF", - "VLREPG", - "VLC", - "VLCB", - "VLCH", - "VLCF", - "VLCG", - "VLEH", - "VLEF", - "VLEG", - "VLEB", - "VLEIH", - "VLEIF", - "VLEIG", - "VLEIB", - "VFI", - "VFIDB", - "WFIDB", - "VLGV", - "VLGVB", - "VLGVH", - "VLGVF", - "VLGVG", - "VLLEZ", - "VLLEZB", - "VLLEZH", - "VLLEZF", - "VLLEZG", - "VLM", - "VLP", - "VLPB", - "VLPH", - "VLPF", - "VLPG", - "VLBB", - "VLVG", - "VLVGB", - "VLVGH", - "VLVGF", - "VLVGG", - "VLVGP", - "VLL", - "VMX", - "VMXB", - "VMXH", - "VMXF", - "VMXG", - "VMXL", - "VMXLB", - "VMXLH", - "VMXLF", - "VMXLG", - "VMRH", - "VMRHB", - "VMRHH", - "VMRHF", - "VMRHG", - "VMRL", - "VMRLB", - "VMRLH", - "VMRLF", - "VMRLG", - "VMN", - "VMNB", - "VMNH", - "VMNF", - "VMNG", - "VMNL", - "VMNLB", - "VMNLH", - "VMNLF", - "VMNLG", - "VMAE", - "VMAEB", - "VMAEH", - "VMAEF", - "VMAH", - "VMAHB", - "VMAHH", - "VMAHF", - "VMALE", - "VMALEB", - "VMALEH", - "VMALEF", - "VMALH", - "VMALHB", - "VMALHH", - "VMALHF", - "VMALO", - "VMALOB", - "VMALOH", - "VMALOF", - "VMAL", - "VMALB", - "VMALHW", - "VMALF", - "VMAO", - "VMAOB", - "VMAOH", - "VMAOF", - "VME", - "VMEB", - "VMEH", - "VMEF", - "VMH", - "VMHB", - "VMHH", - "VMHF", - "VMLE", - "VMLEB", - "VMLEH", - "VMLEF", - "VMLH", - "VMLHB", - "VMLHH", - "VMLHF", - "VMLO", - "VMLOB", - "VMLOH", - "VMLOF", - "VML", - "VMLB", - "VMLHW", - "VMLF", - "VMO", - "VMOB", - "VMOH", - "VMOF", - "VNO", - "VNOT", - "VO", - "VPK", - "VPKH", - "VPKF", - "VPKG", - "VPKLS", - "VPKLSH", - "VPKLSF", - "VPKLSG", - "VPKLSHS", - "VPKLSFS", - "VPKLSGS", - "VPKS", - "VPKSH", - "VPKSF", - "VPKSG", - "VPKSHS", - "VPKSFS", - "VPKSGS", - "VPERM", - "VPDI", - "VPOPCT", - "VREP", - "VREPB", - "VREPH", - "VREPF", - "VREPG", - "VREPI", - "VREPIB", - "VREPIH", - "VREPIF", - "VREPIG", - "VSCEF", - "VSCEG", - "VSEL", - "VSL", - "VSLB", - "VSLDB", - "VSRA", - "VSRAB", - "VSRL", - "VSRLB", - "VSEG", - "VSEGB", - "VSEGH", - "VSEGF", - "VST", - "VSTEH", - "VSTEF", - "VSTEG", - "VSTEB", - "VSTM", - "VSTL", - "VSTRC", - "VSTRCB", - "VSTRCH", - "VSTRCF", - "VSTRCBS", - "VSTRCHS", - "VSTRCFS", - "VSTRCZB", - "VSTRCZH", - "VSTRCZF", - "VSTRCZBS", - "VSTRCZHS", - "VSTRCZFS", - "VS", - "VSB", - "VSH", - "VSF", - "VSG", - "VSQ", - "VSCBI", - "VSCBIB", - "VSCBIH", - "VSCBIF", - "VSCBIG", - "VSCBIQ", - "VSBCBI", - "VSBCBIQ", - "VSBI", - "VSBIQ", - "VSUMG", - "VSUMGH", - "VSUMGF", - "VSUMQ", - "VSUMQF", - "VSUMQG", - "VSUM", - "VSUMB", - "VSUMH", - "VTM", - "VUPH", - "VUPHB", - "VUPHH", - "VUPHF", - "VUPLH", - "VUPLHB", - "VUPLHH", - "VUPLHF", - "VUPLL", - "VUPLLB", - "VUPLLH", - "VUPLLF", - "VUPL", - "VUPLB", - "VUPLHW", - "VUPLF", - "BYTE", - "WORD", - "DWORD", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/s390x/anamesz.go b/vendor/github.com/google/gops/internal/obj/s390x/anamesz.go deleted file mode 100644 index 9c9b4d58..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/anamesz.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2016 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 - -var cnamesz = []string{ - "NONE", - "REG", - "FREG", - "VREG", - "AREG", - "ZCON", - "SCON", - "UCON", - "ADDCON", - "ANDCON", - "LCON", - "DCON", - "SACON", - "LACON", - "DACON", - "SBRA", - "LBRA", - "SAUTO", - "LAUTO", - "ZOREG", - "SOREG", - "LOREG", - "TLS_LE", - "TLS_IE", - "GOK", - "ADDR", - "SYMADDR", - "GOTADDR", - "TEXTSIZE", - "ANY", - "NCLASS", -} diff --git a/vendor/github.com/google/gops/internal/obj/s390x/asmz.go b/vendor/github.com/google/gops/internal/obj/s390x/asmz.go deleted file mode 100644 index e3116462..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/asmz.go +++ /dev/null @@ -1,4766 +0,0 @@ -// Based on cmd/internal/obj/ppc64/asm9.go. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package s390x - -import ( - "log" - "math" - "sort" - - "github.com/google/gops/internal/obj" -) - -// instruction layout. -const ( - funcAlign = 16 -) - -type Optab struct { - as obj.As // opcode - a1 uint8 // From - a2 uint8 // Reg - a3 uint8 // From3 - a4 uint8 // To - type_ int8 - param int16 // REGSP for auto variables -} - -var optab = []Optab{ - // instruction, From, Reg, From3, To, type, param - Optab{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0}, - Optab{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0}, - - // move register - Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 0}, - Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 1, 0}, - Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 1, 0}, - Optab{AMOVW, C_REG, C_NONE, C_NONE, C_REG, 1, 0}, - Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 1, 0}, - Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 1, 0}, - Optab{AMOVDBR, C_REG, C_NONE, C_NONE, C_REG, 1, 0}, - - // load constant - Optab{AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, REGSP}, - Optab{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, REGSP}, - Optab{AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, REGSP}, - Optab{AMOVD, C_DCON, C_NONE, C_NONE, C_REG, 3, 0}, - Optab{AMOVW, C_DCON, C_NONE, C_NONE, C_REG, 3, 0}, - Optab{AMOVWZ, C_DCON, C_NONE, C_NONE, C_REG, 3, 0}, - Optab{AMOVB, C_DCON, C_NONE, C_NONE, C_REG, 3, 0}, - Optab{AMOVBZ, C_DCON, C_NONE, C_NONE, C_REG, 3, 0}, - - // store constant - Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0}, - Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0}, - Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0}, - Optab{AMOVBZ, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0}, - Optab{AMOVB, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0}, - Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_LAUTO, 72, REGSP}, - Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_LAUTO, 72, REGSP}, - Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_LAUTO, 72, REGSP}, - Optab{AMOVB, C_LCON, C_NONE, C_NONE, C_LAUTO, 72, REGSP}, - Optab{AMOVBZ, C_LCON, C_NONE, C_NONE, C_LAUTO, 72, REGSP}, - Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_LOREG, 72, 0}, - Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_LOREG, 72, 0}, - Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_LOREG, 72, 0}, - Optab{AMOVB, C_LCON, C_NONE, C_NONE, C_LOREG, 72, 0}, - Optab{AMOVBZ, C_LCON, C_NONE, C_NONE, C_LOREG, 72, 0}, - - // store - Optab{AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVDBR, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVHBR, C_REG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVDBR, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVHBR, C_REG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 0}, - Optab{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 0}, - Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 0}, - Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 0}, - Optab{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 0}, - - // load - Optab{AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVDBR, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVHBR, C_LAUTO, C_NONE, C_NONE, C_REG, 36, REGSP}, - Optab{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVDBR, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVHBR, C_LOREG, C_NONE, C_NONE, C_REG, 36, 0}, - Optab{AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 0}, - Optab{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 0}, - Optab{AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 0}, - Optab{AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 0}, - Optab{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 75, 0}, - - // interlocked load and op - Optab{ALAAG, C_REG, C_REG, C_NONE, C_LOREG, 99, 0}, - - // integer arithmetic - Optab{AADD, C_REG, C_REG, C_NONE, C_REG, 2, 0}, - Optab{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 0}, - Optab{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 0}, - Optab{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 0}, - Optab{AADD, C_LOREG, C_NONE, C_NONE, C_REG, 12, 0}, - Optab{AADD, C_LAUTO, C_NONE, C_NONE, C_REG, 12, REGSP}, - Optab{ASUB, C_LCON, C_REG, C_NONE, C_REG, 21, 0}, - Optab{ASUB, C_LCON, C_NONE, C_NONE, C_REG, 21, 0}, - Optab{ASUB, C_LOREG, C_NONE, C_NONE, C_REG, 12, 0}, - Optab{ASUB, C_LAUTO, C_NONE, C_NONE, C_REG, 12, REGSP}, - Optab{AMULHD, C_REG, C_NONE, C_NONE, C_REG, 4, 0}, - Optab{AMULHD, C_REG, C_REG, C_NONE, C_REG, 4, 0}, - Optab{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 0}, - Optab{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 0}, - Optab{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 0}, - Optab{ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 0}, - Optab{ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 0}, - Optab{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 0}, - - // integer logical - Optab{AAND, C_REG, C_REG, C_NONE, C_REG, 6, 0}, - Optab{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 0}, - Optab{AAND, C_LCON, C_NONE, C_NONE, C_REG, 23, 0}, - Optab{AAND, C_LOREG, C_NONE, C_NONE, C_REG, 12, 0}, - Optab{AAND, C_LAUTO, C_NONE, C_NONE, C_REG, 12, REGSP}, - Optab{AANDW, C_REG, C_REG, C_NONE, C_REG, 6, 0}, - Optab{AANDW, C_REG, C_NONE, C_NONE, C_REG, 6, 0}, - Optab{AANDW, C_LCON, C_NONE, C_NONE, C_REG, 24, 0}, - Optab{AANDW, C_LOREG, C_NONE, C_NONE, C_REG, 12, 0}, - Optab{AANDW, C_LAUTO, C_NONE, C_NONE, C_REG, 12, REGSP}, - Optab{ASLD, C_REG, C_NONE, C_NONE, C_REG, 7, 0}, - Optab{ASLD, C_REG, C_REG, C_NONE, C_REG, 7, 0}, - Optab{ASLD, C_SCON, C_REG, C_NONE, C_REG, 7, 0}, - Optab{ASLD, C_SCON, C_NONE, C_NONE, C_REG, 7, 0}, - - // compare and swap - Optab{ACSG, C_REG, C_REG, C_NONE, C_SOREG, 79, 0}, - - // floating point - Optab{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 0}, - Optab{AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 0}, - Optab{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 0}, - Optab{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 0}, - Optab{AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 0}, - Optab{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 0}, - Optab{AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 0}, - Optab{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, REGSP}, - Optab{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 0}, - Optab{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 0}, - Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, REGSP}, - Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 0}, - Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 0}, - Optab{AFMOVD, C_ZCON, C_NONE, C_NONE, C_FREG, 67, 0}, - Optab{ACEFBRA, C_REG, C_NONE, C_NONE, C_FREG, 82, 0}, - Optab{ACFEBRA, C_FREG, C_NONE, C_NONE, C_REG, 83, 0}, - Optab{AFIEBR, C_SCON, C_FREG, C_NONE, C_FREG, 48, 0}, - - // load symbol address (plus offset) - Optab{AMOVD, C_SYMADDR, C_NONE, C_NONE, C_REG, 19, 0}, - Optab{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 93, 0}, - Optab{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 94, 0}, - Optab{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 95, 0}, - - // system call - Optab{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 0}, - Optab{ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 0}, - - // branch - Optab{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 0}, - Optab{ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 0}, - Optab{ABC, C_SCON, C_REG, C_NONE, C_LBRA, 16, 0}, - Optab{ABR, C_NONE, C_NONE, C_NONE, C_REG, 18, 0}, - Optab{ABR, C_REG, C_NONE, C_NONE, C_REG, 18, 0}, - Optab{ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 0}, - Optab{ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 0}, - Optab{ACMPBEQ, C_REG, C_REG, C_NONE, C_SBRA, 89, 0}, - Optab{ACMPBEQ, C_REG, C_NONE, C_ADDCON, C_SBRA, 90, 0}, - Optab{ACMPBEQ, C_REG, C_NONE, C_SCON, C_SBRA, 90, 0}, - Optab{ACMPUBEQ, C_REG, C_REG, C_NONE, C_SBRA, 89, 0}, - Optab{ACMPUBEQ, C_REG, C_NONE, C_ANDCON, C_SBRA, 90, 0}, - - // move on condition - Optab{AMOVDEQ, C_REG, C_NONE, C_NONE, C_REG, 17, 0}, - - // find leftmost one - Optab{AFLOGR, C_REG, C_NONE, C_NONE, C_REG, 8, 0}, - - // compare - Optab{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 0}, - Optab{ACMP, C_REG, C_NONE, C_NONE, C_LCON, 71, 0}, - Optab{ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 0}, - Optab{ACMPU, C_REG, C_NONE, C_NONE, C_LCON, 71, 0}, - Optab{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 0}, - Optab{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 0}, - - // 32-bit access registers - Optab{AMOVW, C_AREG, C_NONE, C_NONE, C_REG, 68, 0}, - Optab{AMOVWZ, C_AREG, C_NONE, C_NONE, C_REG, 68, 0}, - Optab{AMOVW, C_REG, C_NONE, C_NONE, C_AREG, 69, 0}, - Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_AREG, 69, 0}, - - // macros - Optab{ACLEAR, C_LCON, C_NONE, C_NONE, C_LOREG, 96, 0}, - Optab{ACLEAR, C_LCON, C_NONE, C_NONE, C_LAUTO, 96, REGSP}, - - // load/store multiple - Optab{ASTMG, C_REG, C_REG, C_NONE, C_LOREG, 97, 0}, - Optab{ASTMG, C_REG, C_REG, C_NONE, C_LAUTO, 97, REGSP}, - Optab{ALMG, C_LOREG, C_REG, C_NONE, C_REG, 98, 0}, - Optab{ALMG, C_LAUTO, C_REG, C_NONE, C_REG, 98, REGSP}, - - // bytes - Optab{ABYTE, C_SCON, C_NONE, C_NONE, C_NONE, 40, 0}, - Optab{AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 0}, - Optab{ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 0}, - Optab{ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 0}, - - // fast synchronization - Optab{ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 81, 0}, - - // store clock - Optab{ASTCK, C_NONE, C_NONE, C_NONE, C_SAUTO, 88, REGSP}, - Optab{ASTCK, C_NONE, C_NONE, C_NONE, C_SOREG, 88, 0}, - - // storage and storage - Optab{AMVC, C_LOREG, C_NONE, C_SCON, C_LOREG, 84, 0}, - Optab{AMVC, C_LOREG, C_NONE, C_SCON, C_LAUTO, 84, REGSP}, - Optab{AMVC, C_LAUTO, C_NONE, C_SCON, C_LAUTO, 84, REGSP}, - - // address - Optab{ALARL, C_LCON, C_NONE, C_NONE, C_REG, 85, 0}, - Optab{ALARL, C_SYMADDR, C_NONE, C_NONE, C_REG, 85, 0}, - Optab{ALA, C_SOREG, C_NONE, C_NONE, C_REG, 86, 0}, - Optab{ALA, C_SAUTO, C_NONE, C_NONE, C_REG, 86, REGSP}, - Optab{AEXRL, C_SYMADDR, C_NONE, C_NONE, C_REG, 87, 0}, - - // misc - Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 0}, - Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0}, - Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0}, - Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0}, - Optab{obj.ANOP, C_SAUTO, C_NONE, C_NONE, C_NONE, 0, 0}, - - // vector instructions - - // VRX store - Optab{AVST, C_VREG, C_NONE, C_NONE, C_SOREG, 100, 0}, - Optab{AVST, C_VREG, C_NONE, C_NONE, C_SAUTO, 100, REGSP}, - Optab{AVSTEG, C_VREG, C_NONE, C_SCON, C_SOREG, 100, 0}, - Optab{AVSTEG, C_VREG, C_NONE, C_SCON, C_SAUTO, 100, REGSP}, - - // VRX load - Optab{AVL, C_SOREG, C_NONE, C_NONE, C_VREG, 101, 0}, - Optab{AVL, C_SAUTO, C_NONE, C_NONE, C_VREG, 101, REGSP}, - Optab{AVLEG, C_SOREG, C_NONE, C_SCON, C_VREG, 101, 0}, - Optab{AVLEG, C_SAUTO, C_NONE, C_SCON, C_VREG, 101, REGSP}, - - // VRV scatter - Optab{AVSCEG, C_VREG, C_NONE, C_SCON, C_SOREG, 102, 0}, - Optab{AVSCEG, C_VREG, C_NONE, C_SCON, C_SAUTO, 102, REGSP}, - - // VRV gather - Optab{AVGEG, C_SOREG, C_NONE, C_SCON, C_VREG, 103, 0}, - Optab{AVGEG, C_SAUTO, C_NONE, C_SCON, C_VREG, 103, REGSP}, - - // VRS element shift/rotate and load gr to/from vr element - Optab{AVESLG, C_SCON, C_VREG, C_NONE, C_VREG, 104, 0}, - Optab{AVESLG, C_REG, C_VREG, C_NONE, C_VREG, 104, 0}, - Optab{AVESLG, C_SCON, C_NONE, C_NONE, C_VREG, 104, 0}, - Optab{AVESLG, C_REG, C_NONE, C_NONE, C_VREG, 104, 0}, - Optab{AVLGVG, C_SCON, C_VREG, C_NONE, C_REG, 104, 0}, - Optab{AVLGVG, C_REG, C_VREG, C_NONE, C_REG, 104, 0}, - Optab{AVLVGG, C_SCON, C_REG, C_NONE, C_VREG, 104, 0}, - Optab{AVLVGG, C_REG, C_REG, C_NONE, C_VREG, 104, 0}, - - // VRS store multiple - Optab{AVSTM, C_VREG, C_VREG, C_NONE, C_SOREG, 105, 0}, - Optab{AVSTM, C_VREG, C_VREG, C_NONE, C_SAUTO, 105, REGSP}, - - // VRS load multiple - Optab{AVLM, C_SOREG, C_VREG, C_NONE, C_VREG, 106, 0}, - Optab{AVLM, C_SAUTO, C_VREG, C_NONE, C_VREG, 106, REGSP}, - - // VRS store with length - Optab{AVSTL, C_VREG, C_NONE, C_REG, C_SOREG, 107, 0}, - Optab{AVSTL, C_VREG, C_NONE, C_REG, C_SAUTO, 107, REGSP}, - - // VRS load with length - Optab{AVLL, C_SOREG, C_NONE, C_REG, C_VREG, 108, 0}, - Optab{AVLL, C_SAUTO, C_NONE, C_REG, C_VREG, 108, REGSP}, - - // VRI-a - Optab{AVGBM, C_ANDCON, C_NONE, C_NONE, C_VREG, 109, 0}, - Optab{AVZERO, C_NONE, C_NONE, C_NONE, C_VREG, 109, 0}, - Optab{AVREPIG, C_ADDCON, C_NONE, C_NONE, C_VREG, 109, 0}, - Optab{AVREPIG, C_SCON, C_NONE, C_NONE, C_VREG, 109, 0}, - Optab{AVLEIG, C_ADDCON, C_NONE, C_SCON, C_VREG, 109, 0}, - Optab{AVLEIG, C_SCON, C_NONE, C_SCON, C_VREG, 109, 0}, - - // VRI-b generate mask - Optab{AVGMG, C_SCON, C_NONE, C_SCON, C_VREG, 110, 0}, - - // VRI-c replicate - Optab{AVREPG, C_UCON, C_VREG, C_NONE, C_VREG, 111, 0}, - - // VRI-d element rotate and insert under mask and - // shift left double by byte - Optab{AVERIMG, C_VREG, C_VREG, C_SCON, C_VREG, 112, 0}, - Optab{AVSLDB, C_VREG, C_VREG, C_SCON, C_VREG, 112, 0}, - - // VRI-d fp test data class immediate - Optab{AVFTCIDB, C_SCON, C_VREG, C_NONE, C_VREG, 113, 0}, - - // VRR-a load reg - Optab{AVLR, C_VREG, C_NONE, C_NONE, C_VREG, 114, 0}, - - // VRR-a compare - Optab{AVECG, C_VREG, C_NONE, C_NONE, C_VREG, 115, 0}, - - // VRR-b - Optab{AVCEQG, C_VREG, C_VREG, C_NONE, C_VREG, 117, 0}, - Optab{AVFAEF, C_VREG, C_VREG, C_NONE, C_VREG, 117, 0}, - Optab{AVPKSG, C_VREG, C_VREG, C_NONE, C_VREG, 117, 0}, - - // VRR-c - Optab{AVAQ, C_VREG, C_VREG, C_NONE, C_VREG, 118, 0}, - Optab{AVAQ, C_VREG, C_NONE, C_NONE, C_VREG, 118, 0}, - Optab{AVNOT, C_VREG, C_NONE, C_NONE, C_VREG, 118, 0}, - Optab{AVPDI, C_VREG, C_VREG, C_SCON, C_VREG, 123, 0}, - - // VRR-c shifts - Optab{AVERLLVG, C_VREG, C_VREG, C_NONE, C_VREG, 119, 0}, - Optab{AVERLLVG, C_VREG, C_NONE, C_NONE, C_VREG, 119, 0}, - - // VRR-d - // 2 3 1 4 - Optab{AVACQ, C_VREG, C_VREG, C_VREG, C_VREG, 120, 0}, - - // VRR-e - Optab{AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 121, 0}, - - // VRR-f - Optab{AVLVGP, C_REG, C_REG, C_NONE, C_VREG, 122, 0}, -} - -var oprange [ALAST & obj.AMask][]Optab - -var xcmp [C_NCLASS][C_NCLASS]bool - -func spanz(ctxt *obj.Link, cursym *obj.LSym) { - p := cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - ctxt.Cursym = cursym - ctxt.Autosize = int32(p.To.Offset) - - if oprange[AORW&obj.AMask] == nil { - buildop(ctxt) - } - - buffer := make([]byte, 0) - changed := true - loop := 0 - for changed { - if loop > 10 { - ctxt.Diag("stuck in spanz loop") - break - } - changed = false - buffer = buffer[:0] - ctxt.Cursym.R = make([]obj.Reloc, 0) - for p := cursym.Text; p != nil; p = p.Link { - pc := int64(len(buffer)) - if pc != p.Pc { - changed = true - } - p.Pc = pc - ctxt.Pc = p.Pc - ctxt.Curp = p - asmout(ctxt, &buffer) - if pc == int64(len(buffer)) { - switch p.As { - case obj.ANOP, obj.AFUNCDATA, obj.APCDATA, obj.ATEXT: - // ok - default: - ctxt.Diag("zero-width instruction\n%v", p) - } - } - } - loop++ - } - - cursym.Size = int64(len(buffer)) - if cursym.Size%funcAlign != 0 { - cursym.Size += funcAlign - (cursym.Size % funcAlign) - } - cursym.Grow(cursym.Size) - copy(cursym.P, buffer) -} - -func isint32(v int64) bool { - return int64(int32(v)) == v -} - -func isuint32(v uint64) bool { - return uint64(uint32(v)) == v -} - -func aclass(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return C_NONE - - case obj.TYPE_REG: - if REG_R0 <= a.Reg && a.Reg <= REG_R15 { - return C_REG - } - if REG_F0 <= a.Reg && a.Reg <= REG_F15 { - return C_FREG - } - if REG_AR0 <= a.Reg && a.Reg <= REG_AR15 { - return C_AREG - } - if REG_V0 <= a.Reg && a.Reg <= REG_V31 { - return C_VREG - } - return C_GOK - - case obj.TYPE_MEM: - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_STATIC: - if a.Sym == nil { - // must have a symbol - break - } - ctxt.Instoffset = a.Offset - if a.Sym.Type == obj.STLSBSS { - if ctxt.Flag_shared { - return C_TLS_IE // initial exec model - } - return C_TLS_LE // local exec model - } - return C_ADDR - - case obj.NAME_GOTREF: - return C_GOTADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SAUTO - } - return C_LAUTO - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize() - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SAUTO - } - return C_LAUTO - - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if ctxt.Instoffset == 0 { - return C_ZOREG - } - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SOREG - } - return C_LOREG - } - - return C_GOK - - case obj.TYPE_TEXTSIZE: - return C_TEXTSIZE - - case obj.TYPE_FCONST: - if f64, ok := a.Val.(float64); ok && math.Float64bits(f64) == 0 { - return C_ZCON - } - ctxt.Diag("cannot handle the floating point constant %v", a.Val) - - case obj.TYPE_CONST, - obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if a.Reg != 0 { - if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { - return C_SACON - } - if isint32(ctxt.Instoffset) { - return C_LACON - } - return C_DACON - } - goto consize - - case obj.NAME_EXTERN, - obj.NAME_STATIC: - s := a.Sym - if s == nil { - break - } - ctxt.Instoffset = a.Offset - if s.Type == obj.SCONST { - goto consize - } - - return C_SYMADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SACON - } - return C_LACON - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize() - if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { - return C_SACON - } - return C_LACON - } - - return C_GOK - - consize: - if ctxt.Instoffset == 0 { - return C_ZCON - } - if ctxt.Instoffset >= 0 { - if ctxt.Instoffset <= 0x7fff { - return C_SCON - } - if ctxt.Instoffset <= 0xffff { - return C_ANDCON - } - if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */ - return C_UCON - } - if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) { - return C_LCON - } - return C_DCON - } - - if ctxt.Instoffset >= -0x8000 { - return C_ADDCON - } - if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) { - return C_UCON - } - if isint32(ctxt.Instoffset) { - return C_LCON - } - return C_DCON - - case obj.TYPE_BRANCH: - return C_SBRA - } - - return C_GOK -} - -func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { - a1 := int(p.Optab) - if a1 != 0 { - return &optab[a1-1] - } - a1 = int(p.From.Class) - if a1 == 0 { - a1 = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(a1) - } - - a1-- - a3 := C_NONE + 1 - if p.From3 != nil { - a3 = int(p.From3.Class) - if a3 == 0 { - a3 = aclass(ctxt, p.From3) + 1 - p.From3.Class = int8(a3) - } - } - - a3-- - a4 := int(p.To.Class) - if a4 == 0 { - a4 = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(a4) - } - - a4-- - a2 := C_NONE - if p.Reg != 0 { - if REG_R0 <= p.Reg && p.Reg <= REG_R15 { - a2 = C_REG - } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 { - a2 = C_VREG - } else if REG_F0 <= p.Reg && p.Reg <= REG_F15 { - a2 = C_FREG - } else if REG_AR0 <= p.Reg && p.Reg <= REG_AR15 { - a2 = C_AREG - } - } - - ops := oprange[p.As&obj.AMask] - c1 := &xcmp[a1] - c2 := &xcmp[a2] - c3 := &xcmp[a3] - c4 := &xcmp[a4] - for i := range ops { - op := &ops[i] - if (int(op.a2) == a2 || c2[op.a2]) && c4[op.a4] && c1[op.a1] && c3[op.a3] { - p.Optab = uint16(cap(optab) - cap(ops) + i + 1) - return op - } - } - - // cannot find a case; abort - ctxt.Diag("illegal combination %v %v %v %v %v\n", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4)) - ctxt.Diag("prog: %v\n", p) - return nil -} - -func cmp(a int, b int) bool { - if a == b { - return true - } - switch a { - case C_DCON: - if b == C_LCON { - return true - } - fallthrough - case C_LCON: - if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON { - return true - } - - case C_ADDCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_ANDCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_UCON: - if b == C_ZCON || b == C_SCON { - return true - } - - case C_SCON: - if b == C_ZCON { - return true - } - - case C_LACON: - if b == C_SACON { - return true - } - - case C_LBRA: - if b == C_SBRA { - return true - } - - case C_LAUTO: - if b == C_SAUTO { - return true - } - - case C_LOREG: - if b == C_ZOREG || b == C_SOREG { - return true - } - - case C_SOREG: - if b == C_ZOREG { - return true - } - - case C_ANY: - return true - } - - return false -} - -type ocmp []Optab - -func (x ocmp) Len() int { - return len(x) -} - -func (x ocmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x ocmp) Less(i, j int) bool { - p1 := &x[i] - p2 := &x[j] - n := int(p1.as) - int(p2.as) - if n != 0 { - return n < 0 - } - n = int(p1.a1) - int(p2.a1) - if n != 0 { - return n < 0 - } - n = int(p1.a2) - int(p2.a2) - if n != 0 { - return n < 0 - } - n = int(p1.a3) - int(p2.a3) - if n != 0 { - return n < 0 - } - n = int(p1.a4) - int(p2.a4) - if n != 0 { - return n < 0 - } - return false -} -func opset(a, b obj.As) { - oprange[a&obj.AMask] = oprange[b&obj.AMask] -} - -func buildop(ctxt *obj.Link) { - for i := 0; i < C_NCLASS; i++ { - for n := 0; n < C_NCLASS; n++ { - if cmp(n, i) { - xcmp[i][n] = true - } - } - } - sort.Sort(ocmp(optab)) - for i := 0; i < len(optab); i++ { - r := optab[i].as - start := i - for ; i+1 < len(optab); i++ { - if optab[i+1].as != r { - break - } - } - oprange[r&obj.AMask] = optab[start : i+1] - - // opset() aliases optab ranges for similar instructions, to reduce the number of optabs in the array. - // oprange[] is used by oplook() to find the Optab entry that applies to a given Prog. - switch r { - case AADD: - opset(AADDC, r) - opset(AADDW, r) - opset(AMULLD, r) - opset(AMULLW, r) - case ADIVW: - opset(AADDE, r) - opset(ADIVD, r) - opset(ADIVDU, r) - opset(ADIVWU, r) - opset(AMODD, r) - opset(AMODDU, r) - opset(AMODW, r) - opset(AMODWU, r) - case AMULHD: - opset(AMULHDU, r) - case AMOVBZ: - opset(AMOVH, r) - opset(AMOVHZ, r) - case ALA: - opset(ALAY, r) - case AMVC: - opset(ACLC, r) - opset(AXC, r) - opset(AOC, r) - opset(ANC, r) - case ASTCK: - opset(ASTCKC, r) - opset(ASTCKE, r) - opset(ASTCKF, r) - case ALAAG: - opset(ALAA, r) - opset(ALAAL, r) - opset(ALAALG, r) - opset(ALAN, r) - opset(ALANG, r) - opset(ALAX, r) - opset(ALAXG, r) - opset(ALAO, r) - opset(ALAOG, r) - case ASTMG: - opset(ASTMY, r) - case ALMG: - opset(ALMY, r) - case ABEQ: - opset(ABGE, r) - opset(ABGT, r) - opset(ABLE, r) - opset(ABLT, r) - opset(ABNE, r) - opset(ABVC, r) - opset(ABVS, r) - opset(ABLEU, r) - opset(ABLTU, r) - case ABR: - opset(ABL, r) - case ABC: - opset(ABCL, r) - case AFABS: - opset(AFNABS, r) - opset(AFNEG, r) - opset(AFNEGS, r) - opset(ALEDBR, r) - opset(ALDEBR, r) - opset(AFSQRT, r) - opset(AFSQRTS, r) - case AFADD: - opset(AFADDS, r) - opset(AFDIV, r) - opset(AFDIVS, r) - opset(AFSUB, r) - opset(AFSUBS, r) - case AFMADD: - opset(AFMADDS, r) - opset(AFMSUB, r) - opset(AFMSUBS, r) - opset(AFNMADD, r) - opset(AFNMADDS, r) - opset(AFNMSUB, r) - opset(AFNMSUBS, r) - case AFMUL: - opset(AFMULS, r) - case AFCMPO: - opset(AFCMPU, r) - opset(ACEBR, r) - case AAND: - opset(AOR, r) - opset(AXOR, r) - case AANDW: - opset(AORW, r) - opset(AXORW, r) - case ASLD: - opset(ASRD, r) - opset(ASLW, r) - opset(ASRW, r) - opset(ASRAD, r) - opset(ASRAW, r) - opset(ARLL, r) - opset(ARLLG, r) - case ACSG: - opset(ACS, r) - case ASUB: - opset(ASUBC, r) - opset(ASUBE, r) - opset(ASUBW, r) - case ANEG: - opset(ANEGW, r) - case AFMOVD: - opset(AFMOVS, r) - case AMOVDBR: - opset(AMOVWBR, r) - case ACMP: - opset(ACMPW, r) - case ACMPU: - opset(ACMPWU, r) - case ACEFBRA: - opset(ACDFBRA, r) - opset(ACEGBRA, r) - opset(ACDGBRA, r) - opset(ACELFBR, r) - opset(ACDLFBR, r) - opset(ACELGBR, r) - opset(ACDLGBR, r) - case ACFEBRA: - opset(ACFDBRA, r) - opset(ACGEBRA, r) - opset(ACGDBRA, r) - opset(ACLFEBR, r) - opset(ACLFDBR, r) - opset(ACLGEBR, r) - opset(ACLGDBR, r) - case AFIEBR: - opset(AFIDBR, r) - case ACMPBEQ: - opset(ACMPBGE, r) - opset(ACMPBGT, r) - opset(ACMPBLE, r) - opset(ACMPBLT, r) - opset(ACMPBNE, r) - case ACMPUBEQ: - opset(ACMPUBGE, r) - opset(ACMPUBGT, r) - opset(ACMPUBLE, r) - opset(ACMPUBLT, r) - opset(ACMPUBNE, r) - case AMOVDEQ: - opset(AMOVDGE, r) - opset(AMOVDGT, r) - opset(AMOVDLE, r) - opset(AMOVDLT, r) - opset(AMOVDNE, r) - case AVL: - opset(AVLLEZB, r) - opset(AVLLEZH, r) - opset(AVLLEZF, r) - opset(AVLLEZG, r) - opset(AVLREPB, r) - opset(AVLREPH, r) - opset(AVLREPF, r) - opset(AVLREPG, r) - case AVLEG: - opset(AVLBB, r) - opset(AVLEB, r) - opset(AVLEH, r) - opset(AVLEF, r) - opset(AVLEG, r) - opset(AVLREP, r) - case AVSTEG: - opset(AVSTEB, r) - opset(AVSTEH, r) - opset(AVSTEF, r) - case AVSCEG: - opset(AVSCEF, r) - case AVGEG: - opset(AVGEF, r) - case AVESLG: - opset(AVESLB, r) - opset(AVESLH, r) - opset(AVESLF, r) - opset(AVERLLB, r) - opset(AVERLLH, r) - opset(AVERLLF, r) - opset(AVERLLG, r) - opset(AVESRAB, r) - opset(AVESRAH, r) - opset(AVESRAF, r) - opset(AVESRAG, r) - opset(AVESRLB, r) - opset(AVESRLH, r) - opset(AVESRLF, r) - opset(AVESRLG, r) - case AVLGVG: - opset(AVLGVB, r) - opset(AVLGVH, r) - opset(AVLGVF, r) - case AVLVGG: - opset(AVLVGB, r) - opset(AVLVGH, r) - opset(AVLVGF, r) - case AVZERO: - opset(AVONE, r) - case AVREPIG: - opset(AVREPIB, r) - opset(AVREPIH, r) - opset(AVREPIF, r) - case AVLEIG: - opset(AVLEIB, r) - opset(AVLEIH, r) - opset(AVLEIF, r) - case AVGMG: - opset(AVGMB, r) - opset(AVGMH, r) - opset(AVGMF, r) - case AVREPG: - opset(AVREPB, r) - opset(AVREPH, r) - opset(AVREPF, r) - case AVERIMG: - opset(AVERIMB, r) - opset(AVERIMH, r) - opset(AVERIMF, r) - case AVFTCIDB: - opset(AWFTCIDB, r) - case AVLR: - opset(AVUPHB, r) - opset(AVUPHH, r) - opset(AVUPHF, r) - opset(AVUPLHB, r) - opset(AVUPLHH, r) - opset(AVUPLHF, r) - opset(AVUPLB, r) - opset(AVUPLHW, r) - opset(AVUPLF, r) - opset(AVUPLLB, r) - opset(AVUPLLH, r) - opset(AVUPLLF, r) - opset(AVCLZB, r) - opset(AVCLZH, r) - opset(AVCLZF, r) - opset(AVCLZG, r) - opset(AVCTZB, r) - opset(AVCTZH, r) - opset(AVCTZF, r) - opset(AVCTZG, r) - opset(AVLDEB, r) - opset(AWLDEB, r) - opset(AVFLCDB, r) - opset(AWFLCDB, r) - opset(AVFLNDB, r) - opset(AWFLNDB, r) - opset(AVFLPDB, r) - opset(AWFLPDB, r) - opset(AVFSQDB, r) - opset(AWFSQDB, r) - opset(AVISTRB, r) - opset(AVISTRH, r) - opset(AVISTRF, r) - opset(AVISTRBS, r) - opset(AVISTRHS, r) - opset(AVISTRFS, r) - opset(AVLCB, r) - opset(AVLCH, r) - opset(AVLCF, r) - opset(AVLCG, r) - opset(AVLPB, r) - opset(AVLPH, r) - opset(AVLPF, r) - opset(AVLPG, r) - opset(AVPOPCT, r) - opset(AVSEGB, r) - opset(AVSEGH, r) - opset(AVSEGF, r) - case AVECG: - opset(AVECB, r) - opset(AVECH, r) - opset(AVECF, r) - opset(AVECLB, r) - opset(AVECLH, r) - opset(AVECLF, r) - opset(AVECLG, r) - opset(AWFCDB, r) - opset(AWFKDB, r) - case AVCEQG: - opset(AVCEQB, r) - opset(AVCEQH, r) - opset(AVCEQF, r) - opset(AVCEQBS, r) - opset(AVCEQHS, r) - opset(AVCEQFS, r) - opset(AVCEQGS, r) - opset(AVCHB, r) - opset(AVCHH, r) - opset(AVCHF, r) - opset(AVCHG, r) - opset(AVCHBS, r) - opset(AVCHHS, r) - opset(AVCHFS, r) - opset(AVCHGS, r) - opset(AVCHLB, r) - opset(AVCHLH, r) - opset(AVCHLF, r) - opset(AVCHLG, r) - opset(AVCHLBS, r) - opset(AVCHLHS, r) - opset(AVCHLFS, r) - opset(AVCHLGS, r) - case AVFAEF: - opset(AVFAEB, r) - opset(AVFAEH, r) - opset(AVFAEBS, r) - opset(AVFAEHS, r) - opset(AVFAEFS, r) - opset(AVFAEZB, r) - opset(AVFAEZH, r) - opset(AVFAEZF, r) - opset(AVFAEZBS, r) - opset(AVFAEZHS, r) - opset(AVFAEZFS, r) - opset(AVFEEB, r) - opset(AVFEEH, r) - opset(AVFEEF, r) - opset(AVFEEBS, r) - opset(AVFEEHS, r) - opset(AVFEEFS, r) - opset(AVFEEZB, r) - opset(AVFEEZH, r) - opset(AVFEEZF, r) - opset(AVFEEZBS, r) - opset(AVFEEZHS, r) - opset(AVFEEZFS, r) - opset(AVFENEB, r) - opset(AVFENEH, r) - opset(AVFENEF, r) - opset(AVFENEBS, r) - opset(AVFENEHS, r) - opset(AVFENEFS, r) - opset(AVFENEZB, r) - opset(AVFENEZH, r) - opset(AVFENEZF, r) - opset(AVFENEZBS, r) - opset(AVFENEZHS, r) - opset(AVFENEZFS, r) - case AVPKSG: - opset(AVPKSH, r) - opset(AVPKSF, r) - opset(AVPKSHS, r) - opset(AVPKSFS, r) - opset(AVPKSGS, r) - opset(AVPKLSH, r) - opset(AVPKLSF, r) - opset(AVPKLSG, r) - opset(AVPKLSHS, r) - opset(AVPKLSFS, r) - opset(AVPKLSGS, r) - case AVAQ: - opset(AVAB, r) - opset(AVAH, r) - opset(AVAF, r) - opset(AVAG, r) - opset(AVACCB, r) - opset(AVACCH, r) - opset(AVACCF, r) - opset(AVACCG, r) - opset(AVACCQ, r) - opset(AVN, r) - opset(AVNC, r) - opset(AVAVGB, r) - opset(AVAVGH, r) - opset(AVAVGF, r) - opset(AVAVGG, r) - opset(AVAVGLB, r) - opset(AVAVGLH, r) - opset(AVAVGLF, r) - opset(AVAVGLG, r) - opset(AVCKSM, r) - opset(AVX, r) - opset(AVFADB, r) - opset(AWFADB, r) - opset(AVFCEDB, r) - opset(AVFCEDBS, r) - opset(AWFCEDB, r) - opset(AWFCEDBS, r) - opset(AVFCHDB, r) - opset(AVFCHDBS, r) - opset(AWFCHDB, r) - opset(AWFCHDBS, r) - opset(AVFCHEDB, r) - opset(AVFCHEDBS, r) - opset(AWFCHEDB, r) - opset(AWFCHEDBS, r) - opset(AVFMDB, r) - opset(AWFMDB, r) - opset(AVGFMB, r) - opset(AVGFMH, r) - opset(AVGFMF, r) - opset(AVGFMG, r) - opset(AVMXB, r) - opset(AVMXH, r) - opset(AVMXF, r) - opset(AVMXG, r) - opset(AVMXLB, r) - opset(AVMXLH, r) - opset(AVMXLF, r) - opset(AVMXLG, r) - opset(AVMNB, r) - opset(AVMNH, r) - opset(AVMNF, r) - opset(AVMNG, r) - opset(AVMNLB, r) - opset(AVMNLH, r) - opset(AVMNLF, r) - opset(AVMNLG, r) - opset(AVMRHB, r) - opset(AVMRHH, r) - opset(AVMRHF, r) - opset(AVMRHG, r) - opset(AVMRLB, r) - opset(AVMRLH, r) - opset(AVMRLF, r) - opset(AVMRLG, r) - opset(AVMEB, r) - opset(AVMEH, r) - opset(AVMEF, r) - opset(AVMLEB, r) - opset(AVMLEH, r) - opset(AVMLEF, r) - opset(AVMOB, r) - opset(AVMOH, r) - opset(AVMOF, r) - opset(AVMLOB, r) - opset(AVMLOH, r) - opset(AVMLOF, r) - opset(AVMHB, r) - opset(AVMHH, r) - opset(AVMHF, r) - opset(AVMLHB, r) - opset(AVMLHH, r) - opset(AVMLHF, r) - opset(AVMLH, r) - opset(AVMLHW, r) - opset(AVMLF, r) - opset(AVNO, r) - opset(AVO, r) - opset(AVPKH, r) - opset(AVPKF, r) - opset(AVPKG, r) - opset(AVSUMGH, r) - opset(AVSUMGF, r) - opset(AVSUMQF, r) - opset(AVSUMQG, r) - opset(AVSUMB, r) - opset(AVSUMH, r) - case AVERLLVG: - opset(AVERLLVB, r) - opset(AVERLLVH, r) - opset(AVERLLVF, r) - opset(AVESLVB, r) - opset(AVESLVH, r) - opset(AVESLVF, r) - opset(AVESLVG, r) - opset(AVESRAVB, r) - opset(AVESRAVH, r) - opset(AVESRAVF, r) - opset(AVESRAVG, r) - opset(AVESRLVB, r) - opset(AVESRLVH, r) - opset(AVESRLVF, r) - opset(AVESRLVG, r) - opset(AVFDDB, r) - opset(AWFDDB, r) - opset(AVFSDB, r) - opset(AWFSDB, r) - opset(AVSL, r) - opset(AVSLB, r) - opset(AVSRA, r) - opset(AVSRAB, r) - opset(AVSRL, r) - opset(AVSRLB, r) - opset(AVSF, r) - opset(AVSG, r) - opset(AVSQ, r) - opset(AVSCBIB, r) - opset(AVSCBIH, r) - opset(AVSCBIF, r) - opset(AVSCBIG, r) - opset(AVSCBIQ, r) - case AVACQ: - opset(AVACCCQ, r) - opset(AVGFMAB, r) - opset(AVGFMAH, r) - opset(AVGFMAF, r) - opset(AVGFMAG, r) - opset(AVMALB, r) - opset(AVMALHW, r) - opset(AVMALF, r) - opset(AVMAHB, r) - opset(AVMAHH, r) - opset(AVMAHF, r) - opset(AVMALHB, r) - opset(AVMALHH, r) - opset(AVMALHF, r) - opset(AVMAEB, r) - opset(AVMAEH, r) - opset(AVMAEF, r) - opset(AVMALEB, r) - opset(AVMALEH, r) - opset(AVMALEF, r) - opset(AVMAOB, r) - opset(AVMAOH, r) - opset(AVMAOF, r) - opset(AVMALOB, r) - opset(AVMALOH, r) - opset(AVMALOF, r) - opset(AVSTRCB, r) - opset(AVSTRCH, r) - opset(AVSTRCF, r) - opset(AVSTRCBS, r) - opset(AVSTRCHS, r) - opset(AVSTRCFS, r) - opset(AVSTRCZB, r) - opset(AVSTRCZH, r) - opset(AVSTRCZF, r) - opset(AVSTRCZBS, r) - opset(AVSTRCZHS, r) - opset(AVSTRCZFS, r) - opset(AVSBCBIQ, r) - opset(AVSBIQ, r) - case AVSEL: - opset(AVFMADB, r) - opset(AWFMADB, r) - opset(AVFMSDB, r) - opset(AWFMSDB, r) - opset(AVPERM, r) - } - } -} - -const ( - op_A uint32 = 0x5A00 // FORMAT_RX1 ADD (32) - op_AD uint32 = 0x6A00 // FORMAT_RX1 ADD NORMALIZED (long HFP) - op_ADB uint32 = 0xED1A // FORMAT_RXE ADD (long BFP) - op_ADBR uint32 = 0xB31A // FORMAT_RRE ADD (long BFP) - op_ADR uint32 = 0x2A00 // FORMAT_RR ADD NORMALIZED (long HFP) - op_ADTR uint32 = 0xB3D2 // FORMAT_RRF1 ADD (long DFP) - op_ADTRA uint32 = 0xB3D2 // FORMAT_RRF1 ADD (long DFP) - op_AE uint32 = 0x7A00 // FORMAT_RX1 ADD NORMALIZED (short HFP) - op_AEB uint32 = 0xED0A // FORMAT_RXE ADD (short BFP) - op_AEBR uint32 = 0xB30A // FORMAT_RRE ADD (short BFP) - op_AER uint32 = 0x3A00 // FORMAT_RR ADD NORMALIZED (short HFP) - op_AFI uint32 = 0xC209 // FORMAT_RIL1 ADD IMMEDIATE (32) - op_AG uint32 = 0xE308 // FORMAT_RXY1 ADD (64) - op_AGF uint32 = 0xE318 // FORMAT_RXY1 ADD (64<-32) - op_AGFI uint32 = 0xC208 // FORMAT_RIL1 ADD IMMEDIATE (64<-32) - op_AGFR uint32 = 0xB918 // FORMAT_RRE ADD (64<-32) - op_AGHI uint32 = 0xA70B // FORMAT_RI1 ADD HALFWORD IMMEDIATE (64) - op_AGHIK uint32 = 0xECD9 // FORMAT_RIE4 ADD IMMEDIATE (64<-16) - op_AGR uint32 = 0xB908 // FORMAT_RRE ADD (64) - op_AGRK uint32 = 0xB9E8 // FORMAT_RRF1 ADD (64) - op_AGSI uint32 = 0xEB7A // FORMAT_SIY ADD IMMEDIATE (64<-8) - op_AH uint32 = 0x4A00 // FORMAT_RX1 ADD HALFWORD - op_AHHHR uint32 = 0xB9C8 // FORMAT_RRF1 ADD HIGH (32) - op_AHHLR uint32 = 0xB9D8 // FORMAT_RRF1 ADD HIGH (32) - op_AHI uint32 = 0xA70A // FORMAT_RI1 ADD HALFWORD IMMEDIATE (32) - op_AHIK uint32 = 0xECD8 // FORMAT_RIE4 ADD IMMEDIATE (32<-16) - op_AHY uint32 = 0xE37A // FORMAT_RXY1 ADD HALFWORD - op_AIH uint32 = 0xCC08 // FORMAT_RIL1 ADD IMMEDIATE HIGH (32) - op_AL uint32 = 0x5E00 // FORMAT_RX1 ADD LOGICAL (32) - op_ALC uint32 = 0xE398 // FORMAT_RXY1 ADD LOGICAL WITH CARRY (32) - op_ALCG uint32 = 0xE388 // FORMAT_RXY1 ADD LOGICAL WITH CARRY (64) - op_ALCGR uint32 = 0xB988 // FORMAT_RRE ADD LOGICAL WITH CARRY (64) - op_ALCR uint32 = 0xB998 // FORMAT_RRE ADD LOGICAL WITH CARRY (32) - op_ALFI uint32 = 0xC20B // FORMAT_RIL1 ADD LOGICAL IMMEDIATE (32) - op_ALG uint32 = 0xE30A // FORMAT_RXY1 ADD LOGICAL (64) - op_ALGF uint32 = 0xE31A // FORMAT_RXY1 ADD LOGICAL (64<-32) - op_ALGFI uint32 = 0xC20A // FORMAT_RIL1 ADD LOGICAL IMMEDIATE (64<-32) - op_ALGFR uint32 = 0xB91A // FORMAT_RRE ADD LOGICAL (64<-32) - op_ALGHSIK uint32 = 0xECDB // FORMAT_RIE4 ADD LOGICAL WITH SIGNED IMMEDIATE (64<-16) - op_ALGR uint32 = 0xB90A // FORMAT_RRE ADD LOGICAL (64) - op_ALGRK uint32 = 0xB9EA // FORMAT_RRF1 ADD LOGICAL (64) - op_ALGSI uint32 = 0xEB7E // FORMAT_SIY ADD LOGICAL WITH SIGNED IMMEDIATE (64<-8) - op_ALHHHR uint32 = 0xB9CA // FORMAT_RRF1 ADD LOGICAL HIGH (32) - op_ALHHLR uint32 = 0xB9DA // FORMAT_RRF1 ADD LOGICAL HIGH (32) - op_ALHSIK uint32 = 0xECDA // FORMAT_RIE4 ADD LOGICAL WITH SIGNED IMMEDIATE (32<-16) - op_ALR uint32 = 0x1E00 // FORMAT_RR ADD LOGICAL (32) - op_ALRK uint32 = 0xB9FA // FORMAT_RRF1 ADD LOGICAL (32) - op_ALSI uint32 = 0xEB6E // FORMAT_SIY ADD LOGICAL WITH SIGNED IMMEDIATE (32<-8) - op_ALSIH uint32 = 0xCC0A // FORMAT_RIL1 ADD LOGICAL WITH SIGNED IMMEDIATE HIGH (32) - op_ALSIHN uint32 = 0xCC0B // FORMAT_RIL1 ADD LOGICAL WITH SIGNED IMMEDIATE HIGH (32) - op_ALY uint32 = 0xE35E // FORMAT_RXY1 ADD LOGICAL (32) - op_AP uint32 = 0xFA00 // FORMAT_SS2 ADD DECIMAL - op_AR uint32 = 0x1A00 // FORMAT_RR ADD (32) - op_ARK uint32 = 0xB9F8 // FORMAT_RRF1 ADD (32) - op_ASI uint32 = 0xEB6A // FORMAT_SIY ADD IMMEDIATE (32<-8) - op_AU uint32 = 0x7E00 // FORMAT_RX1 ADD UNNORMALIZED (short HFP) - op_AUR uint32 = 0x3E00 // FORMAT_RR ADD UNNORMALIZED (short HFP) - op_AW uint32 = 0x6E00 // FORMAT_RX1 ADD UNNORMALIZED (long HFP) - op_AWR uint32 = 0x2E00 // FORMAT_RR ADD UNNORMALIZED (long HFP) - op_AXBR uint32 = 0xB34A // FORMAT_RRE ADD (extended BFP) - op_AXR uint32 = 0x3600 // FORMAT_RR ADD NORMALIZED (extended HFP) - op_AXTR uint32 = 0xB3DA // FORMAT_RRF1 ADD (extended DFP) - op_AXTRA uint32 = 0xB3DA // FORMAT_RRF1 ADD (extended DFP) - op_AY uint32 = 0xE35A // FORMAT_RXY1 ADD (32) - op_BAKR uint32 = 0xB240 // FORMAT_RRE BRANCH AND STACK - op_BAL uint32 = 0x4500 // FORMAT_RX1 BRANCH AND LINK - op_BALR uint32 = 0x0500 // FORMAT_RR BRANCH AND LINK - op_BAS uint32 = 0x4D00 // FORMAT_RX1 BRANCH AND SAVE - op_BASR uint32 = 0x0D00 // FORMAT_RR BRANCH AND SAVE - op_BASSM uint32 = 0x0C00 // FORMAT_RR BRANCH AND SAVE AND SET MODE - op_BC uint32 = 0x4700 // FORMAT_RX2 BRANCH ON CONDITION - op_BCR uint32 = 0x0700 // FORMAT_RR BRANCH ON CONDITION - op_BCT uint32 = 0x4600 // FORMAT_RX1 BRANCH ON COUNT (32) - op_BCTG uint32 = 0xE346 // FORMAT_RXY1 BRANCH ON COUNT (64) - op_BCTGR uint32 = 0xB946 // FORMAT_RRE BRANCH ON COUNT (64) - op_BCTR uint32 = 0x0600 // FORMAT_RR BRANCH ON COUNT (32) - op_BPP uint32 = 0xC700 // FORMAT_SMI BRANCH PREDICTION PRELOAD - op_BPRP uint32 = 0xC500 // FORMAT_MII BRANCH PREDICTION RELATIVE PRELOAD - op_BRAS uint32 = 0xA705 // FORMAT_RI2 BRANCH RELATIVE AND SAVE - op_BRASL uint32 = 0xC005 // FORMAT_RIL2 BRANCH RELATIVE AND SAVE LONG - op_BRC uint32 = 0xA704 // FORMAT_RI3 BRANCH RELATIVE ON CONDITION - op_BRCL uint32 = 0xC004 // FORMAT_RIL3 BRANCH RELATIVE ON CONDITION LONG - op_BRCT uint32 = 0xA706 // FORMAT_RI2 BRANCH RELATIVE ON COUNT (32) - op_BRCTG uint32 = 0xA707 // FORMAT_RI2 BRANCH RELATIVE ON COUNT (64) - op_BRCTH uint32 = 0xCC06 // FORMAT_RIL2 BRANCH RELATIVE ON COUNT HIGH (32) - op_BRXH uint32 = 0x8400 // FORMAT_RSI BRANCH RELATIVE ON INDEX HIGH (32) - op_BRXHG uint32 = 0xEC44 // FORMAT_RIE5 BRANCH RELATIVE ON INDEX HIGH (64) - op_BRXLE uint32 = 0x8500 // FORMAT_RSI BRANCH RELATIVE ON INDEX LOW OR EQ. (32) - op_BRXLG uint32 = 0xEC45 // FORMAT_RIE5 BRANCH RELATIVE ON INDEX LOW OR EQ. (64) - op_BSA uint32 = 0xB25A // FORMAT_RRE BRANCH AND SET AUTHORITY - op_BSG uint32 = 0xB258 // FORMAT_RRE BRANCH IN SUBSPACE GROUP - op_BSM uint32 = 0x0B00 // FORMAT_RR BRANCH AND SET MODE - op_BXH uint32 = 0x8600 // FORMAT_RS1 BRANCH ON INDEX HIGH (32) - op_BXHG uint32 = 0xEB44 // FORMAT_RSY1 BRANCH ON INDEX HIGH (64) - op_BXLE uint32 = 0x8700 // FORMAT_RS1 BRANCH ON INDEX LOW OR EQUAL (32) - op_BXLEG uint32 = 0xEB45 // FORMAT_RSY1 BRANCH ON INDEX LOW OR EQUAL (64) - op_C uint32 = 0x5900 // FORMAT_RX1 COMPARE (32) - op_CD uint32 = 0x6900 // FORMAT_RX1 COMPARE (long HFP) - op_CDB uint32 = 0xED19 // FORMAT_RXE COMPARE (long BFP) - op_CDBR uint32 = 0xB319 // FORMAT_RRE COMPARE (long BFP) - op_CDFBR uint32 = 0xB395 // FORMAT_RRE CONVERT FROM FIXED (32 to long BFP) - op_CDFBRA uint32 = 0xB395 // FORMAT_RRF5 CONVERT FROM FIXED (32 to long BFP) - op_CDFR uint32 = 0xB3B5 // FORMAT_RRE CONVERT FROM FIXED (32 to long HFP) - op_CDFTR uint32 = 0xB951 // FORMAT_RRE CONVERT FROM FIXED (32 to long DFP) - op_CDGBR uint32 = 0xB3A5 // FORMAT_RRE CONVERT FROM FIXED (64 to long BFP) - op_CDGBRA uint32 = 0xB3A5 // FORMAT_RRF5 CONVERT FROM FIXED (64 to long BFP) - op_CDGR uint32 = 0xB3C5 // FORMAT_RRE CONVERT FROM FIXED (64 to long HFP) - op_CDGTR uint32 = 0xB3F1 // FORMAT_RRE CONVERT FROM FIXED (64 to long DFP) - op_CDGTRA uint32 = 0xB3F1 // FORMAT_RRF5 CONVERT FROM FIXED (64 to long DFP) - op_CDLFBR uint32 = 0xB391 // FORMAT_RRF5 CONVERT FROM LOGICAL (32 to long BFP) - op_CDLFTR uint32 = 0xB953 // FORMAT_RRF5 CONVERT FROM LOGICAL (32 to long DFP) - op_CDLGBR uint32 = 0xB3A1 // FORMAT_RRF5 CONVERT FROM LOGICAL (64 to long BFP) - op_CDLGTR uint32 = 0xB952 // FORMAT_RRF5 CONVERT FROM LOGICAL (64 to long DFP) - op_CDR uint32 = 0x2900 // FORMAT_RR COMPARE (long HFP) - op_CDS uint32 = 0xBB00 // FORMAT_RS1 COMPARE DOUBLE AND SWAP (32) - op_CDSG uint32 = 0xEB3E // FORMAT_RSY1 COMPARE DOUBLE AND SWAP (64) - op_CDSTR uint32 = 0xB3F3 // FORMAT_RRE CONVERT FROM SIGNED PACKED (64 to long DFP) - op_CDSY uint32 = 0xEB31 // FORMAT_RSY1 COMPARE DOUBLE AND SWAP (32) - op_CDTR uint32 = 0xB3E4 // FORMAT_RRE COMPARE (long DFP) - op_CDUTR uint32 = 0xB3F2 // FORMAT_RRE CONVERT FROM UNSIGNED PACKED (64 to long DFP) - op_CDZT uint32 = 0xEDAA // FORMAT_RSL CONVERT FROM ZONED (to long DFP) - op_CE uint32 = 0x7900 // FORMAT_RX1 COMPARE (short HFP) - op_CEB uint32 = 0xED09 // FORMAT_RXE COMPARE (short BFP) - op_CEBR uint32 = 0xB309 // FORMAT_RRE COMPARE (short BFP) - op_CEDTR uint32 = 0xB3F4 // FORMAT_RRE COMPARE BIASED EXPONENT (long DFP) - op_CEFBR uint32 = 0xB394 // FORMAT_RRE CONVERT FROM FIXED (32 to short BFP) - op_CEFBRA uint32 = 0xB394 // FORMAT_RRF5 CONVERT FROM FIXED (32 to short BFP) - op_CEFR uint32 = 0xB3B4 // FORMAT_RRE CONVERT FROM FIXED (32 to short HFP) - op_CEGBR uint32 = 0xB3A4 // FORMAT_RRE CONVERT FROM FIXED (64 to short BFP) - op_CEGBRA uint32 = 0xB3A4 // FORMAT_RRF5 CONVERT FROM FIXED (64 to short BFP) - op_CEGR uint32 = 0xB3C4 // FORMAT_RRE CONVERT FROM FIXED (64 to short HFP) - op_CELFBR uint32 = 0xB390 // FORMAT_RRF5 CONVERT FROM LOGICAL (32 to short BFP) - op_CELGBR uint32 = 0xB3A0 // FORMAT_RRF5 CONVERT FROM LOGICAL (64 to short BFP) - op_CER uint32 = 0x3900 // FORMAT_RR COMPARE (short HFP) - op_CEXTR uint32 = 0xB3FC // FORMAT_RRE COMPARE BIASED EXPONENT (extended DFP) - op_CFC uint32 = 0xB21A // FORMAT_S COMPARE AND FORM CODEWORD - op_CFDBR uint32 = 0xB399 // FORMAT_RRF5 CONVERT TO FIXED (long BFP to 32) - op_CFDBRA uint32 = 0xB399 // FORMAT_RRF5 CONVERT TO FIXED (long BFP to 32) - op_CFDR uint32 = 0xB3B9 // FORMAT_RRF5 CONVERT TO FIXED (long HFP to 32) - op_CFDTR uint32 = 0xB941 // FORMAT_RRF5 CONVERT TO FIXED (long DFP to 32) - op_CFEBR uint32 = 0xB398 // FORMAT_RRF5 CONVERT TO FIXED (short BFP to 32) - op_CFEBRA uint32 = 0xB398 // FORMAT_RRF5 CONVERT TO FIXED (short BFP to 32) - op_CFER uint32 = 0xB3B8 // FORMAT_RRF5 CONVERT TO FIXED (short HFP to 32) - op_CFI uint32 = 0xC20D // FORMAT_RIL1 COMPARE IMMEDIATE (32) - op_CFXBR uint32 = 0xB39A // FORMAT_RRF5 CONVERT TO FIXED (extended BFP to 32) - op_CFXBRA uint32 = 0xB39A // FORMAT_RRF5 CONVERT TO FIXED (extended BFP to 32) - op_CFXR uint32 = 0xB3BA // FORMAT_RRF5 CONVERT TO FIXED (extended HFP to 32) - op_CFXTR uint32 = 0xB949 // FORMAT_RRF5 CONVERT TO FIXED (extended DFP to 32) - op_CG uint32 = 0xE320 // FORMAT_RXY1 COMPARE (64) - op_CGDBR uint32 = 0xB3A9 // FORMAT_RRF5 CONVERT TO FIXED (long BFP to 64) - op_CGDBRA uint32 = 0xB3A9 // FORMAT_RRF5 CONVERT TO FIXED (long BFP to 64) - op_CGDR uint32 = 0xB3C9 // FORMAT_RRF5 CONVERT TO FIXED (long HFP to 64) - op_CGDTR uint32 = 0xB3E1 // FORMAT_RRF5 CONVERT TO FIXED (long DFP to 64) - op_CGDTRA uint32 = 0xB3E1 // FORMAT_RRF5 CONVERT TO FIXED (long DFP to 64) - op_CGEBR uint32 = 0xB3A8 // FORMAT_RRF5 CONVERT TO FIXED (short BFP to 64) - op_CGEBRA uint32 = 0xB3A8 // FORMAT_RRF5 CONVERT TO FIXED (short BFP to 64) - op_CGER uint32 = 0xB3C8 // FORMAT_RRF5 CONVERT TO FIXED (short HFP to 64) - op_CGF uint32 = 0xE330 // FORMAT_RXY1 COMPARE (64<-32) - op_CGFI uint32 = 0xC20C // FORMAT_RIL1 COMPARE IMMEDIATE (64<-32) - op_CGFR uint32 = 0xB930 // FORMAT_RRE COMPARE (64<-32) - op_CGFRL uint32 = 0xC60C // FORMAT_RIL2 COMPARE RELATIVE LONG (64<-32) - op_CGH uint32 = 0xE334 // FORMAT_RXY1 COMPARE HALFWORD (64<-16) - op_CGHI uint32 = 0xA70F // FORMAT_RI1 COMPARE HALFWORD IMMEDIATE (64<-16) - op_CGHRL uint32 = 0xC604 // FORMAT_RIL2 COMPARE HALFWORD RELATIVE LONG (64<-16) - op_CGHSI uint32 = 0xE558 // FORMAT_SIL COMPARE HALFWORD IMMEDIATE (64<-16) - op_CGIB uint32 = 0xECFC // FORMAT_RIS COMPARE IMMEDIATE AND BRANCH (64<-8) - op_CGIJ uint32 = 0xEC7C // FORMAT_RIE3 COMPARE IMMEDIATE AND BRANCH RELATIVE (64<-8) - op_CGIT uint32 = 0xEC70 // FORMAT_RIE1 COMPARE IMMEDIATE AND TRAP (64<-16) - op_CGR uint32 = 0xB920 // FORMAT_RRE COMPARE (64) - op_CGRB uint32 = 0xECE4 // FORMAT_RRS COMPARE AND BRANCH (64) - op_CGRJ uint32 = 0xEC64 // FORMAT_RIE2 COMPARE AND BRANCH RELATIVE (64) - op_CGRL uint32 = 0xC608 // FORMAT_RIL2 COMPARE RELATIVE LONG (64) - op_CGRT uint32 = 0xB960 // FORMAT_RRF3 COMPARE AND TRAP (64) - op_CGXBR uint32 = 0xB3AA // FORMAT_RRF5 CONVERT TO FIXED (extended BFP to 64) - op_CGXBRA uint32 = 0xB3AA // FORMAT_RRF5 CONVERT TO FIXED (extended BFP to 64) - op_CGXR uint32 = 0xB3CA // FORMAT_RRF5 CONVERT TO FIXED (extended HFP to 64) - op_CGXTR uint32 = 0xB3E9 // FORMAT_RRF5 CONVERT TO FIXED (extended DFP to 64) - op_CGXTRA uint32 = 0xB3E9 // FORMAT_RRF5 CONVERT TO FIXED (extended DFP to 64) - op_CH uint32 = 0x4900 // FORMAT_RX1 COMPARE HALFWORD (32<-16) - op_CHF uint32 = 0xE3CD // FORMAT_RXY1 COMPARE HIGH (32) - op_CHHR uint32 = 0xB9CD // FORMAT_RRE COMPARE HIGH (32) - op_CHHSI uint32 = 0xE554 // FORMAT_SIL COMPARE HALFWORD IMMEDIATE (16) - op_CHI uint32 = 0xA70E // FORMAT_RI1 COMPARE HALFWORD IMMEDIATE (32<-16) - op_CHLR uint32 = 0xB9DD // FORMAT_RRE COMPARE HIGH (32) - op_CHRL uint32 = 0xC605 // FORMAT_RIL2 COMPARE HALFWORD RELATIVE LONG (32<-16) - op_CHSI uint32 = 0xE55C // FORMAT_SIL COMPARE HALFWORD IMMEDIATE (32<-16) - op_CHY uint32 = 0xE379 // FORMAT_RXY1 COMPARE HALFWORD (32<-16) - op_CIB uint32 = 0xECFE // FORMAT_RIS COMPARE IMMEDIATE AND BRANCH (32<-8) - op_CIH uint32 = 0xCC0D // FORMAT_RIL1 COMPARE IMMEDIATE HIGH (32) - op_CIJ uint32 = 0xEC7E // FORMAT_RIE3 COMPARE IMMEDIATE AND BRANCH RELATIVE (32<-8) - op_CIT uint32 = 0xEC72 // FORMAT_RIE1 COMPARE IMMEDIATE AND TRAP (32<-16) - op_CKSM uint32 = 0xB241 // FORMAT_RRE CHECKSUM - op_CL uint32 = 0x5500 // FORMAT_RX1 COMPARE LOGICAL (32) - op_CLC uint32 = 0xD500 // FORMAT_SS1 COMPARE LOGICAL (character) - op_CLCL uint32 = 0x0F00 // FORMAT_RR COMPARE LOGICAL LONG - op_CLCLE uint32 = 0xA900 // FORMAT_RS1 COMPARE LOGICAL LONG EXTENDED - op_CLCLU uint32 = 0xEB8F // FORMAT_RSY1 COMPARE LOGICAL LONG UNICODE - op_CLFDBR uint32 = 0xB39D // FORMAT_RRF5 CONVERT TO LOGICAL (long BFP to 32) - op_CLFDTR uint32 = 0xB943 // FORMAT_RRF5 CONVERT TO LOGICAL (long DFP to 32) - op_CLFEBR uint32 = 0xB39C // FORMAT_RRF5 CONVERT TO LOGICAL (short BFP to 32) - op_CLFHSI uint32 = 0xE55D // FORMAT_SIL COMPARE LOGICAL IMMEDIATE (32<-16) - op_CLFI uint32 = 0xC20F // FORMAT_RIL1 COMPARE LOGICAL IMMEDIATE (32) - op_CLFIT uint32 = 0xEC73 // FORMAT_RIE1 COMPARE LOGICAL IMMEDIATE AND TRAP (32<-16) - op_CLFXBR uint32 = 0xB39E // FORMAT_RRF5 CONVERT TO LOGICAL (extended BFP to 32) - op_CLFXTR uint32 = 0xB94B // FORMAT_RRF5 CONVERT TO LOGICAL (extended DFP to 32) - op_CLG uint32 = 0xE321 // FORMAT_RXY1 COMPARE LOGICAL (64) - op_CLGDBR uint32 = 0xB3AD // FORMAT_RRF5 CONVERT TO LOGICAL (long BFP to 64) - op_CLGDTR uint32 = 0xB942 // FORMAT_RRF5 CONVERT TO LOGICAL (long DFP to 64) - op_CLGEBR uint32 = 0xB3AC // FORMAT_RRF5 CONVERT TO LOGICAL (short BFP to 64) - op_CLGF uint32 = 0xE331 // FORMAT_RXY1 COMPARE LOGICAL (64<-32) - op_CLGFI uint32 = 0xC20E // FORMAT_RIL1 COMPARE LOGICAL IMMEDIATE (64<-32) - op_CLGFR uint32 = 0xB931 // FORMAT_RRE COMPARE LOGICAL (64<-32) - op_CLGFRL uint32 = 0xC60E // FORMAT_RIL2 COMPARE LOGICAL RELATIVE LONG (64<-32) - op_CLGHRL uint32 = 0xC606 // FORMAT_RIL2 COMPARE LOGICAL RELATIVE LONG (64<-16) - op_CLGHSI uint32 = 0xE559 // FORMAT_SIL COMPARE LOGICAL IMMEDIATE (64<-16) - op_CLGIB uint32 = 0xECFD // FORMAT_RIS COMPARE LOGICAL IMMEDIATE AND BRANCH (64<-8) - op_CLGIJ uint32 = 0xEC7D // FORMAT_RIE3 COMPARE LOGICAL IMMEDIATE AND BRANCH RELATIVE (64<-8) - op_CLGIT uint32 = 0xEC71 // FORMAT_RIE1 COMPARE LOGICAL IMMEDIATE AND TRAP (64<-16) - op_CLGR uint32 = 0xB921 // FORMAT_RRE COMPARE LOGICAL (64) - op_CLGRB uint32 = 0xECE5 // FORMAT_RRS COMPARE LOGICAL AND BRANCH (64) - op_CLGRJ uint32 = 0xEC65 // FORMAT_RIE2 COMPARE LOGICAL AND BRANCH RELATIVE (64) - op_CLGRL uint32 = 0xC60A // FORMAT_RIL2 COMPARE LOGICAL RELATIVE LONG (64) - op_CLGRT uint32 = 0xB961 // FORMAT_RRF3 COMPARE LOGICAL AND TRAP (64) - op_CLGT uint32 = 0xEB2B // FORMAT_RSY2 COMPARE LOGICAL AND TRAP (64) - op_CLGXBR uint32 = 0xB3AE // FORMAT_RRF5 CONVERT TO LOGICAL (extended BFP to 64) - op_CLGXTR uint32 = 0xB94A // FORMAT_RRF5 CONVERT TO LOGICAL (extended DFP to 64) - op_CLHF uint32 = 0xE3CF // FORMAT_RXY1 COMPARE LOGICAL HIGH (32) - op_CLHHR uint32 = 0xB9CF // FORMAT_RRE COMPARE LOGICAL HIGH (32) - op_CLHHSI uint32 = 0xE555 // FORMAT_SIL COMPARE LOGICAL IMMEDIATE (16) - op_CLHLR uint32 = 0xB9DF // FORMAT_RRE COMPARE LOGICAL HIGH (32) - op_CLHRL uint32 = 0xC607 // FORMAT_RIL2 COMPARE LOGICAL RELATIVE LONG (32<-16) - op_CLI uint32 = 0x9500 // FORMAT_SI COMPARE LOGICAL (immediate) - op_CLIB uint32 = 0xECFF // FORMAT_RIS COMPARE LOGICAL IMMEDIATE AND BRANCH (32<-8) - op_CLIH uint32 = 0xCC0F // FORMAT_RIL1 COMPARE LOGICAL IMMEDIATE HIGH (32) - op_CLIJ uint32 = 0xEC7F // FORMAT_RIE3 COMPARE LOGICAL IMMEDIATE AND BRANCH RELATIVE (32<-8) - op_CLIY uint32 = 0xEB55 // FORMAT_SIY COMPARE LOGICAL (immediate) - op_CLM uint32 = 0xBD00 // FORMAT_RS2 COMPARE LOGICAL CHAR. UNDER MASK (low) - op_CLMH uint32 = 0xEB20 // FORMAT_RSY2 COMPARE LOGICAL CHAR. UNDER MASK (high) - op_CLMY uint32 = 0xEB21 // FORMAT_RSY2 COMPARE LOGICAL CHAR. UNDER MASK (low) - op_CLR uint32 = 0x1500 // FORMAT_RR COMPARE LOGICAL (32) - op_CLRB uint32 = 0xECF7 // FORMAT_RRS COMPARE LOGICAL AND BRANCH (32) - op_CLRJ uint32 = 0xEC77 // FORMAT_RIE2 COMPARE LOGICAL AND BRANCH RELATIVE (32) - op_CLRL uint32 = 0xC60F // FORMAT_RIL2 COMPARE LOGICAL RELATIVE LONG (32) - op_CLRT uint32 = 0xB973 // FORMAT_RRF3 COMPARE LOGICAL AND TRAP (32) - op_CLST uint32 = 0xB25D // FORMAT_RRE COMPARE LOGICAL STRING - op_CLT uint32 = 0xEB23 // FORMAT_RSY2 COMPARE LOGICAL AND TRAP (32) - op_CLY uint32 = 0xE355 // FORMAT_RXY1 COMPARE LOGICAL (32) - op_CMPSC uint32 = 0xB263 // FORMAT_RRE COMPRESSION CALL - op_CP uint32 = 0xF900 // FORMAT_SS2 COMPARE DECIMAL - op_CPSDR uint32 = 0xB372 // FORMAT_RRF2 COPY SIGN (long) - op_CPYA uint32 = 0xB24D // FORMAT_RRE COPY ACCESS - op_CR uint32 = 0x1900 // FORMAT_RR COMPARE (32) - op_CRB uint32 = 0xECF6 // FORMAT_RRS COMPARE AND BRANCH (32) - op_CRDTE uint32 = 0xB98F // FORMAT_RRF2 COMPARE AND REPLACE DAT TABLE ENTRY - op_CRJ uint32 = 0xEC76 // FORMAT_RIE2 COMPARE AND BRANCH RELATIVE (32) - op_CRL uint32 = 0xC60D // FORMAT_RIL2 COMPARE RELATIVE LONG (32) - op_CRT uint32 = 0xB972 // FORMAT_RRF3 COMPARE AND TRAP (32) - op_CS uint32 = 0xBA00 // FORMAT_RS1 COMPARE AND SWAP (32) - op_CSCH uint32 = 0xB230 // FORMAT_S CLEAR SUBCHANNEL - op_CSDTR uint32 = 0xB3E3 // FORMAT_RRF4 CONVERT TO SIGNED PACKED (long DFP to 64) - op_CSG uint32 = 0xEB30 // FORMAT_RSY1 COMPARE AND SWAP (64) - op_CSP uint32 = 0xB250 // FORMAT_RRE COMPARE AND SWAP AND PURGE - op_CSPG uint32 = 0xB98A // FORMAT_RRE COMPARE AND SWAP AND PURGE - op_CSST uint32 = 0xC802 // FORMAT_SSF COMPARE AND SWAP AND STORE - op_CSXTR uint32 = 0xB3EB // FORMAT_RRF4 CONVERT TO SIGNED PACKED (extended DFP to 128) - op_CSY uint32 = 0xEB14 // FORMAT_RSY1 COMPARE AND SWAP (32) - op_CU12 uint32 = 0xB2A7 // FORMAT_RRF3 CONVERT UTF-8 TO UTF-16 - op_CU14 uint32 = 0xB9B0 // FORMAT_RRF3 CONVERT UTF-8 TO UTF-32 - op_CU21 uint32 = 0xB2A6 // FORMAT_RRF3 CONVERT UTF-16 TO UTF-8 - op_CU24 uint32 = 0xB9B1 // FORMAT_RRF3 CONVERT UTF-16 TO UTF-32 - op_CU41 uint32 = 0xB9B2 // FORMAT_RRE CONVERT UTF-32 TO UTF-8 - op_CU42 uint32 = 0xB9B3 // FORMAT_RRE CONVERT UTF-32 TO UTF-16 - op_CUDTR uint32 = 0xB3E2 // FORMAT_RRE CONVERT TO UNSIGNED PACKED (long DFP to 64) - op_CUSE uint32 = 0xB257 // FORMAT_RRE COMPARE UNTIL SUBSTRING EQUAL - op_CUTFU uint32 = 0xB2A7 // FORMAT_RRF3 CONVERT UTF-8 TO UNICODE - op_CUUTF uint32 = 0xB2A6 // FORMAT_RRF3 CONVERT UNICODE TO UTF-8 - op_CUXTR uint32 = 0xB3EA // FORMAT_RRE CONVERT TO UNSIGNED PACKED (extended DFP to 128) - op_CVB uint32 = 0x4F00 // FORMAT_RX1 CONVERT TO BINARY (32) - op_CVBG uint32 = 0xE30E // FORMAT_RXY1 CONVERT TO BINARY (64) - op_CVBY uint32 = 0xE306 // FORMAT_RXY1 CONVERT TO BINARY (32) - op_CVD uint32 = 0x4E00 // FORMAT_RX1 CONVERT TO DECIMAL (32) - op_CVDG uint32 = 0xE32E // FORMAT_RXY1 CONVERT TO DECIMAL (64) - op_CVDY uint32 = 0xE326 // FORMAT_RXY1 CONVERT TO DECIMAL (32) - op_CXBR uint32 = 0xB349 // FORMAT_RRE COMPARE (extended BFP) - op_CXFBR uint32 = 0xB396 // FORMAT_RRE CONVERT FROM FIXED (32 to extended BFP) - op_CXFBRA uint32 = 0xB396 // FORMAT_RRF5 CONVERT FROM FIXED (32 to extended BFP) - op_CXFR uint32 = 0xB3B6 // FORMAT_RRE CONVERT FROM FIXED (32 to extended HFP) - op_CXFTR uint32 = 0xB959 // FORMAT_RRE CONVERT FROM FIXED (32 to extended DFP) - op_CXGBR uint32 = 0xB3A6 // FORMAT_RRE CONVERT FROM FIXED (64 to extended BFP) - op_CXGBRA uint32 = 0xB3A6 // FORMAT_RRF5 CONVERT FROM FIXED (64 to extended BFP) - op_CXGR uint32 = 0xB3C6 // FORMAT_RRE CONVERT FROM FIXED (64 to extended HFP) - op_CXGTR uint32 = 0xB3F9 // FORMAT_RRE CONVERT FROM FIXED (64 to extended DFP) - op_CXGTRA uint32 = 0xB3F9 // FORMAT_RRF5 CONVERT FROM FIXED (64 to extended DFP) - op_CXLFBR uint32 = 0xB392 // FORMAT_RRF5 CONVERT FROM LOGICAL (32 to extended BFP) - op_CXLFTR uint32 = 0xB95B // FORMAT_RRF5 CONVERT FROM LOGICAL (32 to extended DFP) - op_CXLGBR uint32 = 0xB3A2 // FORMAT_RRF5 CONVERT FROM LOGICAL (64 to extended BFP) - op_CXLGTR uint32 = 0xB95A // FORMAT_RRF5 CONVERT FROM LOGICAL (64 to extended DFP) - op_CXR uint32 = 0xB369 // FORMAT_RRE COMPARE (extended HFP) - op_CXSTR uint32 = 0xB3FB // FORMAT_RRE CONVERT FROM SIGNED PACKED (128 to extended DFP) - op_CXTR uint32 = 0xB3EC // FORMAT_RRE COMPARE (extended DFP) - op_CXUTR uint32 = 0xB3FA // FORMAT_RRE CONVERT FROM UNSIGNED PACKED (128 to ext. DFP) - op_CXZT uint32 = 0xEDAB // FORMAT_RSL CONVERT FROM ZONED (to extended DFP) - op_CY uint32 = 0xE359 // FORMAT_RXY1 COMPARE (32) - op_CZDT uint32 = 0xEDA8 // FORMAT_RSL CONVERT TO ZONED (from long DFP) - op_CZXT uint32 = 0xEDA9 // FORMAT_RSL CONVERT TO ZONED (from extended DFP) - op_D uint32 = 0x5D00 // FORMAT_RX1 DIVIDE (32<-64) - op_DD uint32 = 0x6D00 // FORMAT_RX1 DIVIDE (long HFP) - op_DDB uint32 = 0xED1D // FORMAT_RXE DIVIDE (long BFP) - op_DDBR uint32 = 0xB31D // FORMAT_RRE DIVIDE (long BFP) - op_DDR uint32 = 0x2D00 // FORMAT_RR DIVIDE (long HFP) - op_DDTR uint32 = 0xB3D1 // FORMAT_RRF1 DIVIDE (long DFP) - op_DDTRA uint32 = 0xB3D1 // FORMAT_RRF1 DIVIDE (long DFP) - op_DE uint32 = 0x7D00 // FORMAT_RX1 DIVIDE (short HFP) - op_DEB uint32 = 0xED0D // FORMAT_RXE DIVIDE (short BFP) - op_DEBR uint32 = 0xB30D // FORMAT_RRE DIVIDE (short BFP) - op_DER uint32 = 0x3D00 // FORMAT_RR DIVIDE (short HFP) - op_DIDBR uint32 = 0xB35B // FORMAT_RRF2 DIVIDE TO INTEGER (long BFP) - op_DIEBR uint32 = 0xB353 // FORMAT_RRF2 DIVIDE TO INTEGER (short BFP) - op_DL uint32 = 0xE397 // FORMAT_RXY1 DIVIDE LOGICAL (32<-64) - op_DLG uint32 = 0xE387 // FORMAT_RXY1 DIVIDE LOGICAL (64<-128) - op_DLGR uint32 = 0xB987 // FORMAT_RRE DIVIDE LOGICAL (64<-128) - op_DLR uint32 = 0xB997 // FORMAT_RRE DIVIDE LOGICAL (32<-64) - op_DP uint32 = 0xFD00 // FORMAT_SS2 DIVIDE DECIMAL - op_DR uint32 = 0x1D00 // FORMAT_RR DIVIDE (32<-64) - op_DSG uint32 = 0xE30D // FORMAT_RXY1 DIVIDE SINGLE (64) - op_DSGF uint32 = 0xE31D // FORMAT_RXY1 DIVIDE SINGLE (64<-32) - op_DSGFR uint32 = 0xB91D // FORMAT_RRE DIVIDE SINGLE (64<-32) - op_DSGR uint32 = 0xB90D // FORMAT_RRE DIVIDE SINGLE (64) - op_DXBR uint32 = 0xB34D // FORMAT_RRE DIVIDE (extended BFP) - op_DXR uint32 = 0xB22D // FORMAT_RRE DIVIDE (extended HFP) - op_DXTR uint32 = 0xB3D9 // FORMAT_RRF1 DIVIDE (extended DFP) - op_DXTRA uint32 = 0xB3D9 // FORMAT_RRF1 DIVIDE (extended DFP) - op_EAR uint32 = 0xB24F // FORMAT_RRE EXTRACT ACCESS - op_ECAG uint32 = 0xEB4C // FORMAT_RSY1 EXTRACT CACHE ATTRIBUTE - op_ECTG uint32 = 0xC801 // FORMAT_SSF EXTRACT CPU TIME - op_ED uint32 = 0xDE00 // FORMAT_SS1 EDIT - op_EDMK uint32 = 0xDF00 // FORMAT_SS1 EDIT AND MARK - op_EEDTR uint32 = 0xB3E5 // FORMAT_RRE EXTRACT BIASED EXPONENT (long DFP to 64) - op_EEXTR uint32 = 0xB3ED // FORMAT_RRE EXTRACT BIASED EXPONENT (extended DFP to 64) - op_EFPC uint32 = 0xB38C // FORMAT_RRE EXTRACT FPC - op_EPAIR uint32 = 0xB99A // FORMAT_RRE EXTRACT PRIMARY ASN AND INSTANCE - op_EPAR uint32 = 0xB226 // FORMAT_RRE EXTRACT PRIMARY ASN - op_EPSW uint32 = 0xB98D // FORMAT_RRE EXTRACT PSW - op_EREG uint32 = 0xB249 // FORMAT_RRE EXTRACT STACKED REGISTERS (32) - op_EREGG uint32 = 0xB90E // FORMAT_RRE EXTRACT STACKED REGISTERS (64) - op_ESAIR uint32 = 0xB99B // FORMAT_RRE EXTRACT SECONDARY ASN AND INSTANCE - op_ESAR uint32 = 0xB227 // FORMAT_RRE EXTRACT SECONDARY ASN - op_ESDTR uint32 = 0xB3E7 // FORMAT_RRE EXTRACT SIGNIFICANCE (long DFP) - op_ESEA uint32 = 0xB99D // FORMAT_RRE EXTRACT AND SET EXTENDED AUTHORITY - op_ESTA uint32 = 0xB24A // FORMAT_RRE EXTRACT STACKED STATE - op_ESXTR uint32 = 0xB3EF // FORMAT_RRE EXTRACT SIGNIFICANCE (extended DFP) - op_ETND uint32 = 0xB2EC // FORMAT_RRE EXTRACT TRANSACTION NESTING DEPTH - op_EX uint32 = 0x4400 // FORMAT_RX1 EXECUTE - op_EXRL uint32 = 0xC600 // FORMAT_RIL2 EXECUTE RELATIVE LONG - op_FIDBR uint32 = 0xB35F // FORMAT_RRF5 LOAD FP INTEGER (long BFP) - op_FIDBRA uint32 = 0xB35F // FORMAT_RRF5 LOAD FP INTEGER (long BFP) - op_FIDR uint32 = 0xB37F // FORMAT_RRE LOAD FP INTEGER (long HFP) - op_FIDTR uint32 = 0xB3D7 // FORMAT_RRF5 LOAD FP INTEGER (long DFP) - op_FIEBR uint32 = 0xB357 // FORMAT_RRF5 LOAD FP INTEGER (short BFP) - op_FIEBRA uint32 = 0xB357 // FORMAT_RRF5 LOAD FP INTEGER (short BFP) - op_FIER uint32 = 0xB377 // FORMAT_RRE LOAD FP INTEGER (short HFP) - op_FIXBR uint32 = 0xB347 // FORMAT_RRF5 LOAD FP INTEGER (extended BFP) - op_FIXBRA uint32 = 0xB347 // FORMAT_RRF5 LOAD FP INTEGER (extended BFP) - op_FIXR uint32 = 0xB367 // FORMAT_RRE LOAD FP INTEGER (extended HFP) - op_FIXTR uint32 = 0xB3DF // FORMAT_RRF5 LOAD FP INTEGER (extended DFP) - op_FLOGR uint32 = 0xB983 // FORMAT_RRE FIND LEFTMOST ONE - op_HDR uint32 = 0x2400 // FORMAT_RR HALVE (long HFP) - op_HER uint32 = 0x3400 // FORMAT_RR HALVE (short HFP) - op_HSCH uint32 = 0xB231 // FORMAT_S HALT SUBCHANNEL - op_IAC uint32 = 0xB224 // FORMAT_RRE INSERT ADDRESS SPACE CONTROL - op_IC uint32 = 0x4300 // FORMAT_RX1 INSERT CHARACTER - op_ICM uint32 = 0xBF00 // FORMAT_RS2 INSERT CHARACTERS UNDER MASK (low) - op_ICMH uint32 = 0xEB80 // FORMAT_RSY2 INSERT CHARACTERS UNDER MASK (high) - op_ICMY uint32 = 0xEB81 // FORMAT_RSY2 INSERT CHARACTERS UNDER MASK (low) - op_ICY uint32 = 0xE373 // FORMAT_RXY1 INSERT CHARACTER - op_IDTE uint32 = 0xB98E // FORMAT_RRF2 INVALIDATE DAT TABLE ENTRY - op_IEDTR uint32 = 0xB3F6 // FORMAT_RRF2 INSERT BIASED EXPONENT (64 to long DFP) - op_IEXTR uint32 = 0xB3FE // FORMAT_RRF2 INSERT BIASED EXPONENT (64 to extended DFP) - op_IIHF uint32 = 0xC008 // FORMAT_RIL1 INSERT IMMEDIATE (high) - op_IIHH uint32 = 0xA500 // FORMAT_RI1 INSERT IMMEDIATE (high high) - op_IIHL uint32 = 0xA501 // FORMAT_RI1 INSERT IMMEDIATE (high low) - op_IILF uint32 = 0xC009 // FORMAT_RIL1 INSERT IMMEDIATE (low) - op_IILH uint32 = 0xA502 // FORMAT_RI1 INSERT IMMEDIATE (low high) - op_IILL uint32 = 0xA503 // FORMAT_RI1 INSERT IMMEDIATE (low low) - op_IPK uint32 = 0xB20B // FORMAT_S INSERT PSW KEY - op_IPM uint32 = 0xB222 // FORMAT_RRE INSERT PROGRAM MASK - op_IPTE uint32 = 0xB221 // FORMAT_RRF1 INVALIDATE PAGE TABLE ENTRY - op_ISKE uint32 = 0xB229 // FORMAT_RRE INSERT STORAGE KEY EXTENDED - op_IVSK uint32 = 0xB223 // FORMAT_RRE INSERT VIRTUAL STORAGE KEY - op_KDB uint32 = 0xED18 // FORMAT_RXE COMPARE AND SIGNAL (long BFP) - op_KDBR uint32 = 0xB318 // FORMAT_RRE COMPARE AND SIGNAL (long BFP) - op_KDTR uint32 = 0xB3E0 // FORMAT_RRE COMPARE AND SIGNAL (long DFP) - op_KEB uint32 = 0xED08 // FORMAT_RXE COMPARE AND SIGNAL (short BFP) - op_KEBR uint32 = 0xB308 // FORMAT_RRE COMPARE AND SIGNAL (short BFP) - op_KIMD uint32 = 0xB93E // FORMAT_RRE COMPUTE INTERMEDIATE MESSAGE DIGEST - op_KLMD uint32 = 0xB93F // FORMAT_RRE COMPUTE LAST MESSAGE DIGEST - op_KM uint32 = 0xB92E // FORMAT_RRE CIPHER MESSAGE - op_KMAC uint32 = 0xB91E // FORMAT_RRE COMPUTE MESSAGE AUTHENTICATION CODE - op_KMC uint32 = 0xB92F // FORMAT_RRE CIPHER MESSAGE WITH CHAINING - op_KMCTR uint32 = 0xB92D // FORMAT_RRF2 CIPHER MESSAGE WITH COUNTER - op_KMF uint32 = 0xB92A // FORMAT_RRE CIPHER MESSAGE WITH CFB - op_KMO uint32 = 0xB92B // FORMAT_RRE CIPHER MESSAGE WITH OFB - op_KXBR uint32 = 0xB348 // FORMAT_RRE COMPARE AND SIGNAL (extended BFP) - op_KXTR uint32 = 0xB3E8 // FORMAT_RRE COMPARE AND SIGNAL (extended DFP) - op_L uint32 = 0x5800 // FORMAT_RX1 LOAD (32) - op_LA uint32 = 0x4100 // FORMAT_RX1 LOAD ADDRESS - op_LAA uint32 = 0xEBF8 // FORMAT_RSY1 LOAD AND ADD (32) - op_LAAG uint32 = 0xEBE8 // FORMAT_RSY1 LOAD AND ADD (64) - op_LAAL uint32 = 0xEBFA // FORMAT_RSY1 LOAD AND ADD LOGICAL (32) - op_LAALG uint32 = 0xEBEA // FORMAT_RSY1 LOAD AND ADD LOGICAL (64) - op_LAE uint32 = 0x5100 // FORMAT_RX1 LOAD ADDRESS EXTENDED - op_LAEY uint32 = 0xE375 // FORMAT_RXY1 LOAD ADDRESS EXTENDED - op_LAM uint32 = 0x9A00 // FORMAT_RS1 LOAD ACCESS MULTIPLE - op_LAMY uint32 = 0xEB9A // FORMAT_RSY1 LOAD ACCESS MULTIPLE - op_LAN uint32 = 0xEBF4 // FORMAT_RSY1 LOAD AND AND (32) - op_LANG uint32 = 0xEBE4 // FORMAT_RSY1 LOAD AND AND (64) - op_LAO uint32 = 0xEBF6 // FORMAT_RSY1 LOAD AND OR (32) - op_LAOG uint32 = 0xEBE6 // FORMAT_RSY1 LOAD AND OR (64) - op_LARL uint32 = 0xC000 // FORMAT_RIL2 LOAD ADDRESS RELATIVE LONG - op_LASP uint32 = 0xE500 // FORMAT_SSE LOAD ADDRESS SPACE PARAMETERS - op_LAT uint32 = 0xE39F // FORMAT_RXY1 LOAD AND TRAP (32L<-32) - op_LAX uint32 = 0xEBF7 // FORMAT_RSY1 LOAD AND EXCLUSIVE OR (32) - op_LAXG uint32 = 0xEBE7 // FORMAT_RSY1 LOAD AND EXCLUSIVE OR (64) - op_LAY uint32 = 0xE371 // FORMAT_RXY1 LOAD ADDRESS - op_LB uint32 = 0xE376 // FORMAT_RXY1 LOAD BYTE (32) - op_LBH uint32 = 0xE3C0 // FORMAT_RXY1 LOAD BYTE HIGH (32<-8) - op_LBR uint32 = 0xB926 // FORMAT_RRE LOAD BYTE (32) - op_LCDBR uint32 = 0xB313 // FORMAT_RRE LOAD COMPLEMENT (long BFP) - op_LCDFR uint32 = 0xB373 // FORMAT_RRE LOAD COMPLEMENT (long) - op_LCDR uint32 = 0x2300 // FORMAT_RR LOAD COMPLEMENT (long HFP) - op_LCEBR uint32 = 0xB303 // FORMAT_RRE LOAD COMPLEMENT (short BFP) - op_LCER uint32 = 0x3300 // FORMAT_RR LOAD COMPLEMENT (short HFP) - op_LCGFR uint32 = 0xB913 // FORMAT_RRE LOAD COMPLEMENT (64<-32) - op_LCGR uint32 = 0xB903 // FORMAT_RRE LOAD COMPLEMENT (64) - op_LCR uint32 = 0x1300 // FORMAT_RR LOAD COMPLEMENT (32) - op_LCTL uint32 = 0xB700 // FORMAT_RS1 LOAD CONTROL (32) - op_LCTLG uint32 = 0xEB2F // FORMAT_RSY1 LOAD CONTROL (64) - op_LCXBR uint32 = 0xB343 // FORMAT_RRE LOAD COMPLEMENT (extended BFP) - op_LCXR uint32 = 0xB363 // FORMAT_RRE LOAD COMPLEMENT (extended HFP) - op_LD uint32 = 0x6800 // FORMAT_RX1 LOAD (long) - op_LDE uint32 = 0xED24 // FORMAT_RXE LOAD LENGTHENED (short to long HFP) - op_LDEB uint32 = 0xED04 // FORMAT_RXE LOAD LENGTHENED (short to long BFP) - op_LDEBR uint32 = 0xB304 // FORMAT_RRE LOAD LENGTHENED (short to long BFP) - op_LDER uint32 = 0xB324 // FORMAT_RRE LOAD LENGTHENED (short to long HFP) - op_LDETR uint32 = 0xB3D4 // FORMAT_RRF4 LOAD LENGTHENED (short to long DFP) - op_LDGR uint32 = 0xB3C1 // FORMAT_RRE LOAD FPR FROM GR (64 to long) - op_LDR uint32 = 0x2800 // FORMAT_RR LOAD (long) - op_LDXBR uint32 = 0xB345 // FORMAT_RRE LOAD ROUNDED (extended to long BFP) - op_LDXBRA uint32 = 0xB345 // FORMAT_RRF5 LOAD ROUNDED (extended to long BFP) - op_LDXR uint32 = 0x2500 // FORMAT_RR LOAD ROUNDED (extended to long HFP) - op_LDXTR uint32 = 0xB3DD // FORMAT_RRF5 LOAD ROUNDED (extended to long DFP) - op_LDY uint32 = 0xED65 // FORMAT_RXY1 LOAD (long) - op_LE uint32 = 0x7800 // FORMAT_RX1 LOAD (short) - op_LEDBR uint32 = 0xB344 // FORMAT_RRE LOAD ROUNDED (long to short BFP) - op_LEDBRA uint32 = 0xB344 // FORMAT_RRF5 LOAD ROUNDED (long to short BFP) - op_LEDR uint32 = 0x3500 // FORMAT_RR LOAD ROUNDED (long to short HFP) - op_LEDTR uint32 = 0xB3D5 // FORMAT_RRF5 LOAD ROUNDED (long to short DFP) - op_LER uint32 = 0x3800 // FORMAT_RR LOAD (short) - op_LEXBR uint32 = 0xB346 // FORMAT_RRE LOAD ROUNDED (extended to short BFP) - op_LEXBRA uint32 = 0xB346 // FORMAT_RRF5 LOAD ROUNDED (extended to short BFP) - op_LEXR uint32 = 0xB366 // FORMAT_RRE LOAD ROUNDED (extended to short HFP) - op_LEY uint32 = 0xED64 // FORMAT_RXY1 LOAD (short) - op_LFAS uint32 = 0xB2BD // FORMAT_S LOAD FPC AND SIGNAL - op_LFH uint32 = 0xE3CA // FORMAT_RXY1 LOAD HIGH (32) - op_LFHAT uint32 = 0xE3C8 // FORMAT_RXY1 LOAD HIGH AND TRAP (32H<-32) - op_LFPC uint32 = 0xB29D // FORMAT_S LOAD FPC - op_LG uint32 = 0xE304 // FORMAT_RXY1 LOAD (64) - op_LGAT uint32 = 0xE385 // FORMAT_RXY1 LOAD AND TRAP (64) - op_LGB uint32 = 0xE377 // FORMAT_RXY1 LOAD BYTE (64) - op_LGBR uint32 = 0xB906 // FORMAT_RRE LOAD BYTE (64) - op_LGDR uint32 = 0xB3CD // FORMAT_RRE LOAD GR FROM FPR (long to 64) - op_LGF uint32 = 0xE314 // FORMAT_RXY1 LOAD (64<-32) - op_LGFI uint32 = 0xC001 // FORMAT_RIL1 LOAD IMMEDIATE (64<-32) - op_LGFR uint32 = 0xB914 // FORMAT_RRE LOAD (64<-32) - op_LGFRL uint32 = 0xC40C // FORMAT_RIL2 LOAD RELATIVE LONG (64<-32) - op_LGH uint32 = 0xE315 // FORMAT_RXY1 LOAD HALFWORD (64) - op_LGHI uint32 = 0xA709 // FORMAT_RI1 LOAD HALFWORD IMMEDIATE (64) - op_LGHR uint32 = 0xB907 // FORMAT_RRE LOAD HALFWORD (64) - op_LGHRL uint32 = 0xC404 // FORMAT_RIL2 LOAD HALFWORD RELATIVE LONG (64<-16) - op_LGR uint32 = 0xB904 // FORMAT_RRE LOAD (64) - op_LGRL uint32 = 0xC408 // FORMAT_RIL2 LOAD RELATIVE LONG (64) - op_LH uint32 = 0x4800 // FORMAT_RX1 LOAD HALFWORD (32) - op_LHH uint32 = 0xE3C4 // FORMAT_RXY1 LOAD HALFWORD HIGH (32<-16) - op_LHI uint32 = 0xA708 // FORMAT_RI1 LOAD HALFWORD IMMEDIATE (32) - op_LHR uint32 = 0xB927 // FORMAT_RRE LOAD HALFWORD (32) - op_LHRL uint32 = 0xC405 // FORMAT_RIL2 LOAD HALFWORD RELATIVE LONG (32<-16) - op_LHY uint32 = 0xE378 // FORMAT_RXY1 LOAD HALFWORD (32) - op_LLC uint32 = 0xE394 // FORMAT_RXY1 LOAD LOGICAL CHARACTER (32) - op_LLCH uint32 = 0xE3C2 // FORMAT_RXY1 LOAD LOGICAL CHARACTER HIGH (32<-8) - op_LLCR uint32 = 0xB994 // FORMAT_RRE LOAD LOGICAL CHARACTER (32) - op_LLGC uint32 = 0xE390 // FORMAT_RXY1 LOAD LOGICAL CHARACTER (64) - op_LLGCR uint32 = 0xB984 // FORMAT_RRE LOAD LOGICAL CHARACTER (64) - op_LLGF uint32 = 0xE316 // FORMAT_RXY1 LOAD LOGICAL (64<-32) - op_LLGFAT uint32 = 0xE39D // FORMAT_RXY1 LOAD LOGICAL AND TRAP (64<-32) - op_LLGFR uint32 = 0xB916 // FORMAT_RRE LOAD LOGICAL (64<-32) - op_LLGFRL uint32 = 0xC40E // FORMAT_RIL2 LOAD LOGICAL RELATIVE LONG (64<-32) - op_LLGH uint32 = 0xE391 // FORMAT_RXY1 LOAD LOGICAL HALFWORD (64) - op_LLGHR uint32 = 0xB985 // FORMAT_RRE LOAD LOGICAL HALFWORD (64) - op_LLGHRL uint32 = 0xC406 // FORMAT_RIL2 LOAD LOGICAL HALFWORD RELATIVE LONG (64<-16) - op_LLGT uint32 = 0xE317 // FORMAT_RXY1 LOAD LOGICAL THIRTY ONE BITS - op_LLGTAT uint32 = 0xE39C // FORMAT_RXY1 LOAD LOGICAL THIRTY ONE BITS AND TRAP (64<-31) - op_LLGTR uint32 = 0xB917 // FORMAT_RRE LOAD LOGICAL THIRTY ONE BITS - op_LLH uint32 = 0xE395 // FORMAT_RXY1 LOAD LOGICAL HALFWORD (32) - op_LLHH uint32 = 0xE3C6 // FORMAT_RXY1 LOAD LOGICAL HALFWORD HIGH (32<-16) - op_LLHR uint32 = 0xB995 // FORMAT_RRE LOAD LOGICAL HALFWORD (32) - op_LLHRL uint32 = 0xC402 // FORMAT_RIL2 LOAD LOGICAL HALFWORD RELATIVE LONG (32<-16) - op_LLIHF uint32 = 0xC00E // FORMAT_RIL1 LOAD LOGICAL IMMEDIATE (high) - op_LLIHH uint32 = 0xA50C // FORMAT_RI1 LOAD LOGICAL IMMEDIATE (high high) - op_LLIHL uint32 = 0xA50D // FORMAT_RI1 LOAD LOGICAL IMMEDIATE (high low) - op_LLILF uint32 = 0xC00F // FORMAT_RIL1 LOAD LOGICAL IMMEDIATE (low) - op_LLILH uint32 = 0xA50E // FORMAT_RI1 LOAD LOGICAL IMMEDIATE (low high) - op_LLILL uint32 = 0xA50F // FORMAT_RI1 LOAD LOGICAL IMMEDIATE (low low) - op_LM uint32 = 0x9800 // FORMAT_RS1 LOAD MULTIPLE (32) - op_LMD uint32 = 0xEF00 // FORMAT_SS5 LOAD MULTIPLE DISJOINT - op_LMG uint32 = 0xEB04 // FORMAT_RSY1 LOAD MULTIPLE (64) - op_LMH uint32 = 0xEB96 // FORMAT_RSY1 LOAD MULTIPLE HIGH - op_LMY uint32 = 0xEB98 // FORMAT_RSY1 LOAD MULTIPLE (32) - op_LNDBR uint32 = 0xB311 // FORMAT_RRE LOAD NEGATIVE (long BFP) - op_LNDFR uint32 = 0xB371 // FORMAT_RRE LOAD NEGATIVE (long) - op_LNDR uint32 = 0x2100 // FORMAT_RR LOAD NEGATIVE (long HFP) - op_LNEBR uint32 = 0xB301 // FORMAT_RRE LOAD NEGATIVE (short BFP) - op_LNER uint32 = 0x3100 // FORMAT_RR LOAD NEGATIVE (short HFP) - op_LNGFR uint32 = 0xB911 // FORMAT_RRE LOAD NEGATIVE (64<-32) - op_LNGR uint32 = 0xB901 // FORMAT_RRE LOAD NEGATIVE (64) - op_LNR uint32 = 0x1100 // FORMAT_RR LOAD NEGATIVE (32) - op_LNXBR uint32 = 0xB341 // FORMAT_RRE LOAD NEGATIVE (extended BFP) - op_LNXR uint32 = 0xB361 // FORMAT_RRE LOAD NEGATIVE (extended HFP) - op_LOC uint32 = 0xEBF2 // FORMAT_RSY2 LOAD ON CONDITION (32) - op_LOCG uint32 = 0xEBE2 // FORMAT_RSY2 LOAD ON CONDITION (64) - op_LOCGR uint32 = 0xB9E2 // FORMAT_RRF3 LOAD ON CONDITION (64) - op_LOCR uint32 = 0xB9F2 // FORMAT_RRF3 LOAD ON CONDITION (32) - op_LPD uint32 = 0xC804 // FORMAT_SSF LOAD PAIR DISJOINT (32) - op_LPDBR uint32 = 0xB310 // FORMAT_RRE LOAD POSITIVE (long BFP) - op_LPDFR uint32 = 0xB370 // FORMAT_RRE LOAD POSITIVE (long) - op_LPDG uint32 = 0xC805 // FORMAT_SSF LOAD PAIR DISJOINT (64) - op_LPDR uint32 = 0x2000 // FORMAT_RR LOAD POSITIVE (long HFP) - op_LPEBR uint32 = 0xB300 // FORMAT_RRE LOAD POSITIVE (short BFP) - op_LPER uint32 = 0x3000 // FORMAT_RR LOAD POSITIVE (short HFP) - op_LPGFR uint32 = 0xB910 // FORMAT_RRE LOAD POSITIVE (64<-32) - op_LPGR uint32 = 0xB900 // FORMAT_RRE LOAD POSITIVE (64) - op_LPQ uint32 = 0xE38F // FORMAT_RXY1 LOAD PAIR FROM QUADWORD - op_LPR uint32 = 0x1000 // FORMAT_RR LOAD POSITIVE (32) - op_LPSW uint32 = 0x8200 // FORMAT_S LOAD PSW - op_LPSWE uint32 = 0xB2B2 // FORMAT_S LOAD PSW EXTENDED - op_LPTEA uint32 = 0xB9AA // FORMAT_RRF2 LOAD PAGE TABLE ENTRY ADDRESS - op_LPXBR uint32 = 0xB340 // FORMAT_RRE LOAD POSITIVE (extended BFP) - op_LPXR uint32 = 0xB360 // FORMAT_RRE LOAD POSITIVE (extended HFP) - op_LR uint32 = 0x1800 // FORMAT_RR LOAD (32) - op_LRA uint32 = 0xB100 // FORMAT_RX1 LOAD REAL ADDRESS (32) - op_LRAG uint32 = 0xE303 // FORMAT_RXY1 LOAD REAL ADDRESS (64) - op_LRAY uint32 = 0xE313 // FORMAT_RXY1 LOAD REAL ADDRESS (32) - op_LRDR uint32 = 0x2500 // FORMAT_RR LOAD ROUNDED (extended to long HFP) - op_LRER uint32 = 0x3500 // FORMAT_RR LOAD ROUNDED (long to short HFP) - op_LRL uint32 = 0xC40D // FORMAT_RIL2 LOAD RELATIVE LONG (32) - op_LRV uint32 = 0xE31E // FORMAT_RXY1 LOAD REVERSED (32) - op_LRVG uint32 = 0xE30F // FORMAT_RXY1 LOAD REVERSED (64) - op_LRVGR uint32 = 0xB90F // FORMAT_RRE LOAD REVERSED (64) - op_LRVH uint32 = 0xE31F // FORMAT_RXY1 LOAD REVERSED (16) - op_LRVR uint32 = 0xB91F // FORMAT_RRE LOAD REVERSED (32) - op_LT uint32 = 0xE312 // FORMAT_RXY1 LOAD AND TEST (32) - op_LTDBR uint32 = 0xB312 // FORMAT_RRE LOAD AND TEST (long BFP) - op_LTDR uint32 = 0x2200 // FORMAT_RR LOAD AND TEST (long HFP) - op_LTDTR uint32 = 0xB3D6 // FORMAT_RRE LOAD AND TEST (long DFP) - op_LTEBR uint32 = 0xB302 // FORMAT_RRE LOAD AND TEST (short BFP) - op_LTER uint32 = 0x3200 // FORMAT_RR LOAD AND TEST (short HFP) - op_LTG uint32 = 0xE302 // FORMAT_RXY1 LOAD AND TEST (64) - op_LTGF uint32 = 0xE332 // FORMAT_RXY1 LOAD AND TEST (64<-32) - op_LTGFR uint32 = 0xB912 // FORMAT_RRE LOAD AND TEST (64<-32) - op_LTGR uint32 = 0xB902 // FORMAT_RRE LOAD AND TEST (64) - op_LTR uint32 = 0x1200 // FORMAT_RR LOAD AND TEST (32) - op_LTXBR uint32 = 0xB342 // FORMAT_RRE LOAD AND TEST (extended BFP) - op_LTXR uint32 = 0xB362 // FORMAT_RRE LOAD AND TEST (extended HFP) - op_LTXTR uint32 = 0xB3DE // FORMAT_RRE LOAD AND TEST (extended DFP) - op_LURA uint32 = 0xB24B // FORMAT_RRE LOAD USING REAL ADDRESS (32) - op_LURAG uint32 = 0xB905 // FORMAT_RRE LOAD USING REAL ADDRESS (64) - op_LXD uint32 = 0xED25 // FORMAT_RXE LOAD LENGTHENED (long to extended HFP) - op_LXDB uint32 = 0xED05 // FORMAT_RXE LOAD LENGTHENED (long to extended BFP) - op_LXDBR uint32 = 0xB305 // FORMAT_RRE LOAD LENGTHENED (long to extended BFP) - op_LXDR uint32 = 0xB325 // FORMAT_RRE LOAD LENGTHENED (long to extended HFP) - op_LXDTR uint32 = 0xB3DC // FORMAT_RRF4 LOAD LENGTHENED (long to extended DFP) - op_LXE uint32 = 0xED26 // FORMAT_RXE LOAD LENGTHENED (short to extended HFP) - op_LXEB uint32 = 0xED06 // FORMAT_RXE LOAD LENGTHENED (short to extended BFP) - op_LXEBR uint32 = 0xB306 // FORMAT_RRE LOAD LENGTHENED (short to extended BFP) - op_LXER uint32 = 0xB326 // FORMAT_RRE LOAD LENGTHENED (short to extended HFP) - op_LXR uint32 = 0xB365 // FORMAT_RRE LOAD (extended) - op_LY uint32 = 0xE358 // FORMAT_RXY1 LOAD (32) - op_LZDR uint32 = 0xB375 // FORMAT_RRE LOAD ZERO (long) - op_LZER uint32 = 0xB374 // FORMAT_RRE LOAD ZERO (short) - op_LZXR uint32 = 0xB376 // FORMAT_RRE LOAD ZERO (extended) - op_M uint32 = 0x5C00 // FORMAT_RX1 MULTIPLY (64<-32) - op_MAD uint32 = 0xED3E // FORMAT_RXF MULTIPLY AND ADD (long HFP) - op_MADB uint32 = 0xED1E // FORMAT_RXF MULTIPLY AND ADD (long BFP) - op_MADBR uint32 = 0xB31E // FORMAT_RRD MULTIPLY AND ADD (long BFP) - op_MADR uint32 = 0xB33E // FORMAT_RRD MULTIPLY AND ADD (long HFP) - op_MAE uint32 = 0xED2E // FORMAT_RXF MULTIPLY AND ADD (short HFP) - op_MAEB uint32 = 0xED0E // FORMAT_RXF MULTIPLY AND ADD (short BFP) - op_MAEBR uint32 = 0xB30E // FORMAT_RRD MULTIPLY AND ADD (short BFP) - op_MAER uint32 = 0xB32E // FORMAT_RRD MULTIPLY AND ADD (short HFP) - op_MAY uint32 = 0xED3A // FORMAT_RXF MULTIPLY & ADD UNNORMALIZED (long to ext. HFP) - op_MAYH uint32 = 0xED3C // FORMAT_RXF MULTIPLY AND ADD UNNRM. (long to ext. high HFP) - op_MAYHR uint32 = 0xB33C // FORMAT_RRD MULTIPLY AND ADD UNNRM. (long to ext. high HFP) - op_MAYL uint32 = 0xED38 // FORMAT_RXF MULTIPLY AND ADD UNNRM. (long to ext. low HFP) - op_MAYLR uint32 = 0xB338 // FORMAT_RRD MULTIPLY AND ADD UNNRM. (long to ext. low HFP) - op_MAYR uint32 = 0xB33A // FORMAT_RRD MULTIPLY & ADD UNNORMALIZED (long to ext. HFP) - op_MC uint32 = 0xAF00 // FORMAT_SI MONITOR CALL - op_MD uint32 = 0x6C00 // FORMAT_RX1 MULTIPLY (long HFP) - op_MDB uint32 = 0xED1C // FORMAT_RXE MULTIPLY (long BFP) - op_MDBR uint32 = 0xB31C // FORMAT_RRE MULTIPLY (long BFP) - op_MDE uint32 = 0x7C00 // FORMAT_RX1 MULTIPLY (short to long HFP) - op_MDEB uint32 = 0xED0C // FORMAT_RXE MULTIPLY (short to long BFP) - op_MDEBR uint32 = 0xB30C // FORMAT_RRE MULTIPLY (short to long BFP) - op_MDER uint32 = 0x3C00 // FORMAT_RR MULTIPLY (short to long HFP) - op_MDR uint32 = 0x2C00 // FORMAT_RR MULTIPLY (long HFP) - op_MDTR uint32 = 0xB3D0 // FORMAT_RRF1 MULTIPLY (long DFP) - op_MDTRA uint32 = 0xB3D0 // FORMAT_RRF1 MULTIPLY (long DFP) - op_ME uint32 = 0x7C00 // FORMAT_RX1 MULTIPLY (short to long HFP) - op_MEE uint32 = 0xED37 // FORMAT_RXE MULTIPLY (short HFP) - op_MEEB uint32 = 0xED17 // FORMAT_RXE MULTIPLY (short BFP) - op_MEEBR uint32 = 0xB317 // FORMAT_RRE MULTIPLY (short BFP) - op_MEER uint32 = 0xB337 // FORMAT_RRE MULTIPLY (short HFP) - op_MER uint32 = 0x3C00 // FORMAT_RR MULTIPLY (short to long HFP) - op_MFY uint32 = 0xE35C // FORMAT_RXY1 MULTIPLY (64<-32) - op_MGHI uint32 = 0xA70D // FORMAT_RI1 MULTIPLY HALFWORD IMMEDIATE (64) - op_MH uint32 = 0x4C00 // FORMAT_RX1 MULTIPLY HALFWORD (32) - op_MHI uint32 = 0xA70C // FORMAT_RI1 MULTIPLY HALFWORD IMMEDIATE (32) - op_MHY uint32 = 0xE37C // FORMAT_RXY1 MULTIPLY HALFWORD (32) - op_ML uint32 = 0xE396 // FORMAT_RXY1 MULTIPLY LOGICAL (64<-32) - op_MLG uint32 = 0xE386 // FORMAT_RXY1 MULTIPLY LOGICAL (128<-64) - op_MLGR uint32 = 0xB986 // FORMAT_RRE MULTIPLY LOGICAL (128<-64) - op_MLR uint32 = 0xB996 // FORMAT_RRE MULTIPLY LOGICAL (64<-32) - op_MP uint32 = 0xFC00 // FORMAT_SS2 MULTIPLY DECIMAL - op_MR uint32 = 0x1C00 // FORMAT_RR MULTIPLY (64<-32) - op_MS uint32 = 0x7100 // FORMAT_RX1 MULTIPLY SINGLE (32) - op_MSCH uint32 = 0xB232 // FORMAT_S MODIFY SUBCHANNEL - op_MSD uint32 = 0xED3F // FORMAT_RXF MULTIPLY AND SUBTRACT (long HFP) - op_MSDB uint32 = 0xED1F // FORMAT_RXF MULTIPLY AND SUBTRACT (long BFP) - op_MSDBR uint32 = 0xB31F // FORMAT_RRD MULTIPLY AND SUBTRACT (long BFP) - op_MSDR uint32 = 0xB33F // FORMAT_RRD MULTIPLY AND SUBTRACT (long HFP) - op_MSE uint32 = 0xED2F // FORMAT_RXF MULTIPLY AND SUBTRACT (short HFP) - op_MSEB uint32 = 0xED0F // FORMAT_RXF MULTIPLY AND SUBTRACT (short BFP) - op_MSEBR uint32 = 0xB30F // FORMAT_RRD MULTIPLY AND SUBTRACT (short BFP) - op_MSER uint32 = 0xB32F // FORMAT_RRD MULTIPLY AND SUBTRACT (short HFP) - op_MSFI uint32 = 0xC201 // FORMAT_RIL1 MULTIPLY SINGLE IMMEDIATE (32) - op_MSG uint32 = 0xE30C // FORMAT_RXY1 MULTIPLY SINGLE (64) - op_MSGF uint32 = 0xE31C // FORMAT_RXY1 MULTIPLY SINGLE (64<-32) - op_MSGFI uint32 = 0xC200 // FORMAT_RIL1 MULTIPLY SINGLE IMMEDIATE (64<-32) - op_MSGFR uint32 = 0xB91C // FORMAT_RRE MULTIPLY SINGLE (64<-32) - op_MSGR uint32 = 0xB90C // FORMAT_RRE MULTIPLY SINGLE (64) - op_MSR uint32 = 0xB252 // FORMAT_RRE MULTIPLY SINGLE (32) - op_MSTA uint32 = 0xB247 // FORMAT_RRE MODIFY STACKED STATE - op_MSY uint32 = 0xE351 // FORMAT_RXY1 MULTIPLY SINGLE (32) - op_MVC uint32 = 0xD200 // FORMAT_SS1 MOVE (character) - op_MVCDK uint32 = 0xE50F // FORMAT_SSE MOVE WITH DESTINATION KEY - op_MVCIN uint32 = 0xE800 // FORMAT_SS1 MOVE INVERSE - op_MVCK uint32 = 0xD900 // FORMAT_SS4 MOVE WITH KEY - op_MVCL uint32 = 0x0E00 // FORMAT_RR MOVE LONG - op_MVCLE uint32 = 0xA800 // FORMAT_RS1 MOVE LONG EXTENDED - op_MVCLU uint32 = 0xEB8E // FORMAT_RSY1 MOVE LONG UNICODE - op_MVCOS uint32 = 0xC800 // FORMAT_SSF MOVE WITH OPTIONAL SPECIFICATIONS - op_MVCP uint32 = 0xDA00 // FORMAT_SS4 MOVE TO PRIMARY - op_MVCS uint32 = 0xDB00 // FORMAT_SS4 MOVE TO SECONDARY - op_MVCSK uint32 = 0xE50E // FORMAT_SSE MOVE WITH SOURCE KEY - op_MVGHI uint32 = 0xE548 // FORMAT_SIL MOVE (64<-16) - op_MVHHI uint32 = 0xE544 // FORMAT_SIL MOVE (16<-16) - op_MVHI uint32 = 0xE54C // FORMAT_SIL MOVE (32<-16) - op_MVI uint32 = 0x9200 // FORMAT_SI MOVE (immediate) - op_MVIY uint32 = 0xEB52 // FORMAT_SIY MOVE (immediate) - op_MVN uint32 = 0xD100 // FORMAT_SS1 MOVE NUMERICS - op_MVO uint32 = 0xF100 // FORMAT_SS2 MOVE WITH OFFSET - op_MVPG uint32 = 0xB254 // FORMAT_RRE MOVE PAGE - op_MVST uint32 = 0xB255 // FORMAT_RRE MOVE STRING - op_MVZ uint32 = 0xD300 // FORMAT_SS1 MOVE ZONES - op_MXBR uint32 = 0xB34C // FORMAT_RRE MULTIPLY (extended BFP) - op_MXD uint32 = 0x6700 // FORMAT_RX1 MULTIPLY (long to extended HFP) - op_MXDB uint32 = 0xED07 // FORMAT_RXE MULTIPLY (long to extended BFP) - op_MXDBR uint32 = 0xB307 // FORMAT_RRE MULTIPLY (long to extended BFP) - op_MXDR uint32 = 0x2700 // FORMAT_RR MULTIPLY (long to extended HFP) - op_MXR uint32 = 0x2600 // FORMAT_RR MULTIPLY (extended HFP) - op_MXTR uint32 = 0xB3D8 // FORMAT_RRF1 MULTIPLY (extended DFP) - op_MXTRA uint32 = 0xB3D8 // FORMAT_RRF1 MULTIPLY (extended DFP) - op_MY uint32 = 0xED3B // FORMAT_RXF MULTIPLY UNNORMALIZED (long to ext. HFP) - op_MYH uint32 = 0xED3D // FORMAT_RXF MULTIPLY UNNORM. (long to ext. high HFP) - op_MYHR uint32 = 0xB33D // FORMAT_RRD MULTIPLY UNNORM. (long to ext. high HFP) - op_MYL uint32 = 0xED39 // FORMAT_RXF MULTIPLY UNNORM. (long to ext. low HFP) - op_MYLR uint32 = 0xB339 // FORMAT_RRD MULTIPLY UNNORM. (long to ext. low HFP) - op_MYR uint32 = 0xB33B // FORMAT_RRD MULTIPLY UNNORMALIZED (long to ext. HFP) - op_N uint32 = 0x5400 // FORMAT_RX1 AND (32) - op_NC uint32 = 0xD400 // FORMAT_SS1 AND (character) - op_NG uint32 = 0xE380 // FORMAT_RXY1 AND (64) - op_NGR uint32 = 0xB980 // FORMAT_RRE AND (64) - op_NGRK uint32 = 0xB9E4 // FORMAT_RRF1 AND (64) - op_NI uint32 = 0x9400 // FORMAT_SI AND (immediate) - op_NIAI uint32 = 0xB2FA // FORMAT_IE NEXT INSTRUCTION ACCESS INTENT - op_NIHF uint32 = 0xC00A // FORMAT_RIL1 AND IMMEDIATE (high) - op_NIHH uint32 = 0xA504 // FORMAT_RI1 AND IMMEDIATE (high high) - op_NIHL uint32 = 0xA505 // FORMAT_RI1 AND IMMEDIATE (high low) - op_NILF uint32 = 0xC00B // FORMAT_RIL1 AND IMMEDIATE (low) - op_NILH uint32 = 0xA506 // FORMAT_RI1 AND IMMEDIATE (low high) - op_NILL uint32 = 0xA507 // FORMAT_RI1 AND IMMEDIATE (low low) - op_NIY uint32 = 0xEB54 // FORMAT_SIY AND (immediate) - op_NR uint32 = 0x1400 // FORMAT_RR AND (32) - op_NRK uint32 = 0xB9F4 // FORMAT_RRF1 AND (32) - op_NTSTG uint32 = 0xE325 // FORMAT_RXY1 NONTRANSACTIONAL STORE - op_NY uint32 = 0xE354 // FORMAT_RXY1 AND (32) - op_O uint32 = 0x5600 // FORMAT_RX1 OR (32) - op_OC uint32 = 0xD600 // FORMAT_SS1 OR (character) - op_OG uint32 = 0xE381 // FORMAT_RXY1 OR (64) - op_OGR uint32 = 0xB981 // FORMAT_RRE OR (64) - op_OGRK uint32 = 0xB9E6 // FORMAT_RRF1 OR (64) - op_OI uint32 = 0x9600 // FORMAT_SI OR (immediate) - op_OIHF uint32 = 0xC00C // FORMAT_RIL1 OR IMMEDIATE (high) - op_OIHH uint32 = 0xA508 // FORMAT_RI1 OR IMMEDIATE (high high) - op_OIHL uint32 = 0xA509 // FORMAT_RI1 OR IMMEDIATE (high low) - op_OILF uint32 = 0xC00D // FORMAT_RIL1 OR IMMEDIATE (low) - op_OILH uint32 = 0xA50A // FORMAT_RI1 OR IMMEDIATE (low high) - op_OILL uint32 = 0xA50B // FORMAT_RI1 OR IMMEDIATE (low low) - op_OIY uint32 = 0xEB56 // FORMAT_SIY OR (immediate) - op_OR uint32 = 0x1600 // FORMAT_RR OR (32) - op_ORK uint32 = 0xB9F6 // FORMAT_RRF1 OR (32) - op_OY uint32 = 0xE356 // FORMAT_RXY1 OR (32) - op_PACK uint32 = 0xF200 // FORMAT_SS2 PACK - op_PALB uint32 = 0xB248 // FORMAT_RRE PURGE ALB - op_PC uint32 = 0xB218 // FORMAT_S PROGRAM CALL - op_PCC uint32 = 0xB92C // FORMAT_RRE PERFORM CRYPTOGRAPHIC COMPUTATION - op_PCKMO uint32 = 0xB928 // FORMAT_RRE PERFORM CRYPTOGRAPHIC KEY MGMT. OPERATIONS - op_PFD uint32 = 0xE336 // FORMAT_RXY2 PREFETCH DATA - op_PFDRL uint32 = 0xC602 // FORMAT_RIL3 PREFETCH DATA RELATIVE LONG - op_PFMF uint32 = 0xB9AF // FORMAT_RRE PERFORM FRAME MANAGEMENT FUNCTION - op_PFPO uint32 = 0x010A // FORMAT_E PERFORM FLOATING-POINT OPERATION - op_PGIN uint32 = 0xB22E // FORMAT_RRE PAGE IN - op_PGOUT uint32 = 0xB22F // FORMAT_RRE PAGE OUT - op_PKA uint32 = 0xE900 // FORMAT_SS6 PACK ASCII - op_PKU uint32 = 0xE100 // FORMAT_SS6 PACK UNICODE - op_PLO uint32 = 0xEE00 // FORMAT_SS5 PERFORM LOCKED OPERATION - op_POPCNT uint32 = 0xB9E1 // FORMAT_RRE POPULATION COUNT - op_PPA uint32 = 0xB2E8 // FORMAT_RRF3 PERFORM PROCESSOR ASSIST - op_PR uint32 = 0x0101 // FORMAT_E PROGRAM RETURN - op_PT uint32 = 0xB228 // FORMAT_RRE PROGRAM TRANSFER - op_PTF uint32 = 0xB9A2 // FORMAT_RRE PERFORM TOPOLOGY FUNCTION - op_PTFF uint32 = 0x0104 // FORMAT_E PERFORM TIMING FACILITY FUNCTION - op_PTI uint32 = 0xB99E // FORMAT_RRE PROGRAM TRANSFER WITH INSTANCE - op_PTLB uint32 = 0xB20D // FORMAT_S PURGE TLB - op_QADTR uint32 = 0xB3F5 // FORMAT_RRF2 QUANTIZE (long DFP) - op_QAXTR uint32 = 0xB3FD // FORMAT_RRF2 QUANTIZE (extended DFP) - op_RCHP uint32 = 0xB23B // FORMAT_S RESET CHANNEL PATH - op_RISBG uint32 = 0xEC55 // FORMAT_RIE6 ROTATE THEN INSERT SELECTED BITS - op_RISBGN uint32 = 0xEC59 // FORMAT_RIE6 ROTATE THEN INSERT SELECTED BITS - op_RISBHG uint32 = 0xEC5D // FORMAT_RIE6 ROTATE THEN INSERT SELECTED BITS HIGH - op_RISBLG uint32 = 0xEC51 // FORMAT_RIE6 ROTATE THEN INSERT SELECTED BITS LOW - op_RLL uint32 = 0xEB1D // FORMAT_RSY1 ROTATE LEFT SINGLE LOGICAL (32) - op_RLLG uint32 = 0xEB1C // FORMAT_RSY1 ROTATE LEFT SINGLE LOGICAL (64) - op_RNSBG uint32 = 0xEC54 // FORMAT_RIE6 ROTATE THEN AND SELECTED BITS - op_ROSBG uint32 = 0xEC56 // FORMAT_RIE6 ROTATE THEN OR SELECTED BITS - op_RP uint32 = 0xB277 // FORMAT_S RESUME PROGRAM - op_RRBE uint32 = 0xB22A // FORMAT_RRE RESET REFERENCE BIT EXTENDED - op_RRBM uint32 = 0xB9AE // FORMAT_RRE RESET REFERENCE BITS MULTIPLE - op_RRDTR uint32 = 0xB3F7 // FORMAT_RRF2 REROUND (long DFP) - op_RRXTR uint32 = 0xB3FF // FORMAT_RRF2 REROUND (extended DFP) - op_RSCH uint32 = 0xB238 // FORMAT_S RESUME SUBCHANNEL - op_RXSBG uint32 = 0xEC57 // FORMAT_RIE6 ROTATE THEN EXCLUSIVE OR SELECTED BITS - op_S uint32 = 0x5B00 // FORMAT_RX1 SUBTRACT (32) - op_SAC uint32 = 0xB219 // FORMAT_S SET ADDRESS SPACE CONTROL - op_SACF uint32 = 0xB279 // FORMAT_S SET ADDRESS SPACE CONTROL FAST - op_SAL uint32 = 0xB237 // FORMAT_S SET ADDRESS LIMIT - op_SAM24 uint32 = 0x010C // FORMAT_E SET ADDRESSING MODE (24) - op_SAM31 uint32 = 0x010D // FORMAT_E SET ADDRESSING MODE (31) - op_SAM64 uint32 = 0x010E // FORMAT_E SET ADDRESSING MODE (64) - op_SAR uint32 = 0xB24E // FORMAT_RRE SET ACCESS - op_SCHM uint32 = 0xB23C // FORMAT_S SET CHANNEL MONITOR - op_SCK uint32 = 0xB204 // FORMAT_S SET CLOCK - op_SCKC uint32 = 0xB206 // FORMAT_S SET CLOCK COMPARATOR - op_SCKPF uint32 = 0x0107 // FORMAT_E SET CLOCK PROGRAMMABLE FIELD - op_SD uint32 = 0x6B00 // FORMAT_RX1 SUBTRACT NORMALIZED (long HFP) - op_SDB uint32 = 0xED1B // FORMAT_RXE SUBTRACT (long BFP) - op_SDBR uint32 = 0xB31B // FORMAT_RRE SUBTRACT (long BFP) - op_SDR uint32 = 0x2B00 // FORMAT_RR SUBTRACT NORMALIZED (long HFP) - op_SDTR uint32 = 0xB3D3 // FORMAT_RRF1 SUBTRACT (long DFP) - op_SDTRA uint32 = 0xB3D3 // FORMAT_RRF1 SUBTRACT (long DFP) - op_SE uint32 = 0x7B00 // FORMAT_RX1 SUBTRACT NORMALIZED (short HFP) - op_SEB uint32 = 0xED0B // FORMAT_RXE SUBTRACT (short BFP) - op_SEBR uint32 = 0xB30B // FORMAT_RRE SUBTRACT (short BFP) - op_SER uint32 = 0x3B00 // FORMAT_RR SUBTRACT NORMALIZED (short HFP) - op_SFASR uint32 = 0xB385 // FORMAT_RRE SET FPC AND SIGNAL - op_SFPC uint32 = 0xB384 // FORMAT_RRE SET FPC - op_SG uint32 = 0xE309 // FORMAT_RXY1 SUBTRACT (64) - op_SGF uint32 = 0xE319 // FORMAT_RXY1 SUBTRACT (64<-32) - op_SGFR uint32 = 0xB919 // FORMAT_RRE SUBTRACT (64<-32) - op_SGR uint32 = 0xB909 // FORMAT_RRE SUBTRACT (64) - op_SGRK uint32 = 0xB9E9 // FORMAT_RRF1 SUBTRACT (64) - op_SH uint32 = 0x4B00 // FORMAT_RX1 SUBTRACT HALFWORD - op_SHHHR uint32 = 0xB9C9 // FORMAT_RRF1 SUBTRACT HIGH (32) - op_SHHLR uint32 = 0xB9D9 // FORMAT_RRF1 SUBTRACT HIGH (32) - op_SHY uint32 = 0xE37B // FORMAT_RXY1 SUBTRACT HALFWORD - op_SIGP uint32 = 0xAE00 // FORMAT_RS1 SIGNAL PROCESSOR - op_SL uint32 = 0x5F00 // FORMAT_RX1 SUBTRACT LOGICAL (32) - op_SLA uint32 = 0x8B00 // FORMAT_RS1 SHIFT LEFT SINGLE (32) - op_SLAG uint32 = 0xEB0B // FORMAT_RSY1 SHIFT LEFT SINGLE (64) - op_SLAK uint32 = 0xEBDD // FORMAT_RSY1 SHIFT LEFT SINGLE (32) - op_SLB uint32 = 0xE399 // FORMAT_RXY1 SUBTRACT LOGICAL WITH BORROW (32) - op_SLBG uint32 = 0xE389 // FORMAT_RXY1 SUBTRACT LOGICAL WITH BORROW (64) - op_SLBGR uint32 = 0xB989 // FORMAT_RRE SUBTRACT LOGICAL WITH BORROW (64) - op_SLBR uint32 = 0xB999 // FORMAT_RRE SUBTRACT LOGICAL WITH BORROW (32) - op_SLDA uint32 = 0x8F00 // FORMAT_RS1 SHIFT LEFT DOUBLE - op_SLDL uint32 = 0x8D00 // FORMAT_RS1 SHIFT LEFT DOUBLE LOGICAL - op_SLDT uint32 = 0xED40 // FORMAT_RXF SHIFT SIGNIFICAND LEFT (long DFP) - op_SLFI uint32 = 0xC205 // FORMAT_RIL1 SUBTRACT LOGICAL IMMEDIATE (32) - op_SLG uint32 = 0xE30B // FORMAT_RXY1 SUBTRACT LOGICAL (64) - op_SLGF uint32 = 0xE31B // FORMAT_RXY1 SUBTRACT LOGICAL (64<-32) - op_SLGFI uint32 = 0xC204 // FORMAT_RIL1 SUBTRACT LOGICAL IMMEDIATE (64<-32) - op_SLGFR uint32 = 0xB91B // FORMAT_RRE SUBTRACT LOGICAL (64<-32) - op_SLGR uint32 = 0xB90B // FORMAT_RRE SUBTRACT LOGICAL (64) - op_SLGRK uint32 = 0xB9EB // FORMAT_RRF1 SUBTRACT LOGICAL (64) - op_SLHHHR uint32 = 0xB9CB // FORMAT_RRF1 SUBTRACT LOGICAL HIGH (32) - op_SLHHLR uint32 = 0xB9DB // FORMAT_RRF1 SUBTRACT LOGICAL HIGH (32) - op_SLL uint32 = 0x8900 // FORMAT_RS1 SHIFT LEFT SINGLE LOGICAL (32) - op_SLLG uint32 = 0xEB0D // FORMAT_RSY1 SHIFT LEFT SINGLE LOGICAL (64) - op_SLLK uint32 = 0xEBDF // FORMAT_RSY1 SHIFT LEFT SINGLE LOGICAL (32) - op_SLR uint32 = 0x1F00 // FORMAT_RR SUBTRACT LOGICAL (32) - op_SLRK uint32 = 0xB9FB // FORMAT_RRF1 SUBTRACT LOGICAL (32) - op_SLXT uint32 = 0xED48 // FORMAT_RXF SHIFT SIGNIFICAND LEFT (extended DFP) - op_SLY uint32 = 0xE35F // FORMAT_RXY1 SUBTRACT LOGICAL (32) - op_SP uint32 = 0xFB00 // FORMAT_SS2 SUBTRACT DECIMAL - op_SPKA uint32 = 0xB20A // FORMAT_S SET PSW KEY FROM ADDRESS - op_SPM uint32 = 0x0400 // FORMAT_RR SET PROGRAM MASK - op_SPT uint32 = 0xB208 // FORMAT_S SET CPU TIMER - op_SPX uint32 = 0xB210 // FORMAT_S SET PREFIX - op_SQD uint32 = 0xED35 // FORMAT_RXE SQUARE ROOT (long HFP) - op_SQDB uint32 = 0xED15 // FORMAT_RXE SQUARE ROOT (long BFP) - op_SQDBR uint32 = 0xB315 // FORMAT_RRE SQUARE ROOT (long BFP) - op_SQDR uint32 = 0xB244 // FORMAT_RRE SQUARE ROOT (long HFP) - op_SQE uint32 = 0xED34 // FORMAT_RXE SQUARE ROOT (short HFP) - op_SQEB uint32 = 0xED14 // FORMAT_RXE SQUARE ROOT (short BFP) - op_SQEBR uint32 = 0xB314 // FORMAT_RRE SQUARE ROOT (short BFP) - op_SQER uint32 = 0xB245 // FORMAT_RRE SQUARE ROOT (short HFP) - op_SQXBR uint32 = 0xB316 // FORMAT_RRE SQUARE ROOT (extended BFP) - op_SQXR uint32 = 0xB336 // FORMAT_RRE SQUARE ROOT (extended HFP) - op_SR uint32 = 0x1B00 // FORMAT_RR SUBTRACT (32) - op_SRA uint32 = 0x8A00 // FORMAT_RS1 SHIFT RIGHT SINGLE (32) - op_SRAG uint32 = 0xEB0A // FORMAT_RSY1 SHIFT RIGHT SINGLE (64) - op_SRAK uint32 = 0xEBDC // FORMAT_RSY1 SHIFT RIGHT SINGLE (32) - op_SRDA uint32 = 0x8E00 // FORMAT_RS1 SHIFT RIGHT DOUBLE - op_SRDL uint32 = 0x8C00 // FORMAT_RS1 SHIFT RIGHT DOUBLE LOGICAL - op_SRDT uint32 = 0xED41 // FORMAT_RXF SHIFT SIGNIFICAND RIGHT (long DFP) - op_SRK uint32 = 0xB9F9 // FORMAT_RRF1 SUBTRACT (32) - op_SRL uint32 = 0x8800 // FORMAT_RS1 SHIFT RIGHT SINGLE LOGICAL (32) - op_SRLG uint32 = 0xEB0C // FORMAT_RSY1 SHIFT RIGHT SINGLE LOGICAL (64) - op_SRLK uint32 = 0xEBDE // FORMAT_RSY1 SHIFT RIGHT SINGLE LOGICAL (32) - op_SRNM uint32 = 0xB299 // FORMAT_S SET BFP ROUNDING MODE (2 bit) - op_SRNMB uint32 = 0xB2B8 // FORMAT_S SET BFP ROUNDING MODE (3 bit) - op_SRNMT uint32 = 0xB2B9 // FORMAT_S SET DFP ROUNDING MODE - op_SRP uint32 = 0xF000 // FORMAT_SS3 SHIFT AND ROUND DECIMAL - op_SRST uint32 = 0xB25E // FORMAT_RRE SEARCH STRING - op_SRSTU uint32 = 0xB9BE // FORMAT_RRE SEARCH STRING UNICODE - op_SRXT uint32 = 0xED49 // FORMAT_RXF SHIFT SIGNIFICAND RIGHT (extended DFP) - op_SSAIR uint32 = 0xB99F // FORMAT_RRE SET SECONDARY ASN WITH INSTANCE - op_SSAR uint32 = 0xB225 // FORMAT_RRE SET SECONDARY ASN - op_SSCH uint32 = 0xB233 // FORMAT_S START SUBCHANNEL - op_SSKE uint32 = 0xB22B // FORMAT_RRF3 SET STORAGE KEY EXTENDED - op_SSM uint32 = 0x8000 // FORMAT_S SET SYSTEM MASK - op_ST uint32 = 0x5000 // FORMAT_RX1 STORE (32) - op_STAM uint32 = 0x9B00 // FORMAT_RS1 STORE ACCESS MULTIPLE - op_STAMY uint32 = 0xEB9B // FORMAT_RSY1 STORE ACCESS MULTIPLE - op_STAP uint32 = 0xB212 // FORMAT_S STORE CPU ADDRESS - op_STC uint32 = 0x4200 // FORMAT_RX1 STORE CHARACTER - op_STCH uint32 = 0xE3C3 // FORMAT_RXY1 STORE CHARACTER HIGH (8) - op_STCK uint32 = 0xB205 // FORMAT_S STORE CLOCK - op_STCKC uint32 = 0xB207 // FORMAT_S STORE CLOCK COMPARATOR - op_STCKE uint32 = 0xB278 // FORMAT_S STORE CLOCK EXTENDED - op_STCKF uint32 = 0xB27C // FORMAT_S STORE CLOCK FAST - op_STCM uint32 = 0xBE00 // FORMAT_RS2 STORE CHARACTERS UNDER MASK (low) - op_STCMH uint32 = 0xEB2C // FORMAT_RSY2 STORE CHARACTERS UNDER MASK (high) - op_STCMY uint32 = 0xEB2D // FORMAT_RSY2 STORE CHARACTERS UNDER MASK (low) - op_STCPS uint32 = 0xB23A // FORMAT_S STORE CHANNEL PATH STATUS - op_STCRW uint32 = 0xB239 // FORMAT_S STORE CHANNEL REPORT WORD - op_STCTG uint32 = 0xEB25 // FORMAT_RSY1 STORE CONTROL (64) - op_STCTL uint32 = 0xB600 // FORMAT_RS1 STORE CONTROL (32) - op_STCY uint32 = 0xE372 // FORMAT_RXY1 STORE CHARACTER - op_STD uint32 = 0x6000 // FORMAT_RX1 STORE (long) - op_STDY uint32 = 0xED67 // FORMAT_RXY1 STORE (long) - op_STE uint32 = 0x7000 // FORMAT_RX1 STORE (short) - op_STEY uint32 = 0xED66 // FORMAT_RXY1 STORE (short) - op_STFH uint32 = 0xE3CB // FORMAT_RXY1 STORE HIGH (32) - op_STFL uint32 = 0xB2B1 // FORMAT_S STORE FACILITY LIST - op_STFLE uint32 = 0xB2B0 // FORMAT_S STORE FACILITY LIST EXTENDED - op_STFPC uint32 = 0xB29C // FORMAT_S STORE FPC - op_STG uint32 = 0xE324 // FORMAT_RXY1 STORE (64) - op_STGRL uint32 = 0xC40B // FORMAT_RIL2 STORE RELATIVE LONG (64) - op_STH uint32 = 0x4000 // FORMAT_RX1 STORE HALFWORD - op_STHH uint32 = 0xE3C7 // FORMAT_RXY1 STORE HALFWORD HIGH (16) - op_STHRL uint32 = 0xC407 // FORMAT_RIL2 STORE HALFWORD RELATIVE LONG - op_STHY uint32 = 0xE370 // FORMAT_RXY1 STORE HALFWORD - op_STIDP uint32 = 0xB202 // FORMAT_S STORE CPU ID - op_STM uint32 = 0x9000 // FORMAT_RS1 STORE MULTIPLE (32) - op_STMG uint32 = 0xEB24 // FORMAT_RSY1 STORE MULTIPLE (64) - op_STMH uint32 = 0xEB26 // FORMAT_RSY1 STORE MULTIPLE HIGH - op_STMY uint32 = 0xEB90 // FORMAT_RSY1 STORE MULTIPLE (32) - op_STNSM uint32 = 0xAC00 // FORMAT_SI STORE THEN AND SYSTEM MASK - op_STOC uint32 = 0xEBF3 // FORMAT_RSY2 STORE ON CONDITION (32) - op_STOCG uint32 = 0xEBE3 // FORMAT_RSY2 STORE ON CONDITION (64) - op_STOSM uint32 = 0xAD00 // FORMAT_SI STORE THEN OR SYSTEM MASK - op_STPQ uint32 = 0xE38E // FORMAT_RXY1 STORE PAIR TO QUADWORD - op_STPT uint32 = 0xB209 // FORMAT_S STORE CPU TIMER - op_STPX uint32 = 0xB211 // FORMAT_S STORE PREFIX - op_STRAG uint32 = 0xE502 // FORMAT_SSE STORE REAL ADDRESS - op_STRL uint32 = 0xC40F // FORMAT_RIL2 STORE RELATIVE LONG (32) - op_STRV uint32 = 0xE33E // FORMAT_RXY1 STORE REVERSED (32) - op_STRVG uint32 = 0xE32F // FORMAT_RXY1 STORE REVERSED (64) - op_STRVH uint32 = 0xE33F // FORMAT_RXY1 STORE REVERSED (16) - op_STSCH uint32 = 0xB234 // FORMAT_S STORE SUBCHANNEL - op_STSI uint32 = 0xB27D // FORMAT_S STORE SYSTEM INFORMATION - op_STURA uint32 = 0xB246 // FORMAT_RRE STORE USING REAL ADDRESS (32) - op_STURG uint32 = 0xB925 // FORMAT_RRE STORE USING REAL ADDRESS (64) - op_STY uint32 = 0xE350 // FORMAT_RXY1 STORE (32) - op_SU uint32 = 0x7F00 // FORMAT_RX1 SUBTRACT UNNORMALIZED (short HFP) - op_SUR uint32 = 0x3F00 // FORMAT_RR SUBTRACT UNNORMALIZED (short HFP) - op_SVC uint32 = 0x0A00 // FORMAT_I SUPERVISOR CALL - op_SW uint32 = 0x6F00 // FORMAT_RX1 SUBTRACT UNNORMALIZED (long HFP) - op_SWR uint32 = 0x2F00 // FORMAT_RR SUBTRACT UNNORMALIZED (long HFP) - op_SXBR uint32 = 0xB34B // FORMAT_RRE SUBTRACT (extended BFP) - op_SXR uint32 = 0x3700 // FORMAT_RR SUBTRACT NORMALIZED (extended HFP) - op_SXTR uint32 = 0xB3DB // FORMAT_RRF1 SUBTRACT (extended DFP) - op_SXTRA uint32 = 0xB3DB // FORMAT_RRF1 SUBTRACT (extended DFP) - op_SY uint32 = 0xE35B // FORMAT_RXY1 SUBTRACT (32) - op_TABORT uint32 = 0xB2FC // FORMAT_S TRANSACTION ABORT - op_TAM uint32 = 0x010B // FORMAT_E TEST ADDRESSING MODE - op_TAR uint32 = 0xB24C // FORMAT_RRE TEST ACCESS - op_TB uint32 = 0xB22C // FORMAT_RRE TEST BLOCK - op_TBDR uint32 = 0xB351 // FORMAT_RRF5 CONVERT HFP TO BFP (long) - op_TBEDR uint32 = 0xB350 // FORMAT_RRF5 CONVERT HFP TO BFP (long to short) - op_TBEGIN uint32 = 0xE560 // FORMAT_SIL TRANSACTION BEGIN - op_TBEGINC uint32 = 0xE561 // FORMAT_SIL TRANSACTION BEGIN - op_TCDB uint32 = 0xED11 // FORMAT_RXE TEST DATA CLASS (long BFP) - op_TCEB uint32 = 0xED10 // FORMAT_RXE TEST DATA CLASS (short BFP) - op_TCXB uint32 = 0xED12 // FORMAT_RXE TEST DATA CLASS (extended BFP) - op_TDCDT uint32 = 0xED54 // FORMAT_RXE TEST DATA CLASS (long DFP) - op_TDCET uint32 = 0xED50 // FORMAT_RXE TEST DATA CLASS (short DFP) - op_TDCXT uint32 = 0xED58 // FORMAT_RXE TEST DATA CLASS (extended DFP) - op_TDGDT uint32 = 0xED55 // FORMAT_RXE TEST DATA GROUP (long DFP) - op_TDGET uint32 = 0xED51 // FORMAT_RXE TEST DATA GROUP (short DFP) - op_TDGXT uint32 = 0xED59 // FORMAT_RXE TEST DATA GROUP (extended DFP) - op_TEND uint32 = 0xB2F8 // FORMAT_S TRANSACTION END - op_THDER uint32 = 0xB358 // FORMAT_RRE CONVERT BFP TO HFP (short to long) - op_THDR uint32 = 0xB359 // FORMAT_RRE CONVERT BFP TO HFP (long) - op_TM uint32 = 0x9100 // FORMAT_SI TEST UNDER MASK - op_TMH uint32 = 0xA700 // FORMAT_RI1 TEST UNDER MASK HIGH - op_TMHH uint32 = 0xA702 // FORMAT_RI1 TEST UNDER MASK (high high) - op_TMHL uint32 = 0xA703 // FORMAT_RI1 TEST UNDER MASK (high low) - op_TML uint32 = 0xA701 // FORMAT_RI1 TEST UNDER MASK LOW - op_TMLH uint32 = 0xA700 // FORMAT_RI1 TEST UNDER MASK (low high) - op_TMLL uint32 = 0xA701 // FORMAT_RI1 TEST UNDER MASK (low low) - op_TMY uint32 = 0xEB51 // FORMAT_SIY TEST UNDER MASK - op_TP uint32 = 0xEBC0 // FORMAT_RSL TEST DECIMAL - op_TPI uint32 = 0xB236 // FORMAT_S TEST PENDING INTERRUPTION - op_TPROT uint32 = 0xE501 // FORMAT_SSE TEST PROTECTION - op_TR uint32 = 0xDC00 // FORMAT_SS1 TRANSLATE - op_TRACE uint32 = 0x9900 // FORMAT_RS1 TRACE (32) - op_TRACG uint32 = 0xEB0F // FORMAT_RSY1 TRACE (64) - op_TRAP2 uint32 = 0x01FF // FORMAT_E TRAP - op_TRAP4 uint32 = 0xB2FF // FORMAT_S TRAP - op_TRE uint32 = 0xB2A5 // FORMAT_RRE TRANSLATE EXTENDED - op_TROO uint32 = 0xB993 // FORMAT_RRF3 TRANSLATE ONE TO ONE - op_TROT uint32 = 0xB992 // FORMAT_RRF3 TRANSLATE ONE TO TWO - op_TRT uint32 = 0xDD00 // FORMAT_SS1 TRANSLATE AND TEST - op_TRTE uint32 = 0xB9BF // FORMAT_RRF3 TRANSLATE AND TEST EXTENDED - op_TRTO uint32 = 0xB991 // FORMAT_RRF3 TRANSLATE TWO TO ONE - op_TRTR uint32 = 0xD000 // FORMAT_SS1 TRANSLATE AND TEST REVERSE - op_TRTRE uint32 = 0xB9BD // FORMAT_RRF3 TRANSLATE AND TEST REVERSE EXTENDED - op_TRTT uint32 = 0xB990 // FORMAT_RRF3 TRANSLATE TWO TO TWO - op_TS uint32 = 0x9300 // FORMAT_S TEST AND SET - op_TSCH uint32 = 0xB235 // FORMAT_S TEST SUBCHANNEL - op_UNPK uint32 = 0xF300 // FORMAT_SS2 UNPACK - op_UNPKA uint32 = 0xEA00 // FORMAT_SS1 UNPACK ASCII - op_UNPKU uint32 = 0xE200 // FORMAT_SS1 UNPACK UNICODE - op_UPT uint32 = 0x0102 // FORMAT_E UPDATE TREE - op_X uint32 = 0x5700 // FORMAT_RX1 EXCLUSIVE OR (32) - op_XC uint32 = 0xD700 // FORMAT_SS1 EXCLUSIVE OR (character) - op_XG uint32 = 0xE382 // FORMAT_RXY1 EXCLUSIVE OR (64) - op_XGR uint32 = 0xB982 // FORMAT_RRE EXCLUSIVE OR (64) - op_XGRK uint32 = 0xB9E7 // FORMAT_RRF1 EXCLUSIVE OR (64) - op_XI uint32 = 0x9700 // FORMAT_SI EXCLUSIVE OR (immediate) - op_XIHF uint32 = 0xC006 // FORMAT_RIL1 EXCLUSIVE OR IMMEDIATE (high) - op_XILF uint32 = 0xC007 // FORMAT_RIL1 EXCLUSIVE OR IMMEDIATE (low) - op_XIY uint32 = 0xEB57 // FORMAT_SIY EXCLUSIVE OR (immediate) - op_XR uint32 = 0x1700 // FORMAT_RR EXCLUSIVE OR (32) - op_XRK uint32 = 0xB9F7 // FORMAT_RRF1 EXCLUSIVE OR (32) - op_XSCH uint32 = 0xB276 // FORMAT_S CANCEL SUBCHANNEL - op_XY uint32 = 0xE357 // FORMAT_RXY1 EXCLUSIVE OR (32) - op_ZAP uint32 = 0xF800 // FORMAT_SS2 ZERO AND ADD - - // added in z13 - op_CXPT uint32 = 0xEDAF // RSL-b CONVERT FROM PACKED (to extended DFP) - op_CDPT uint32 = 0xEDAE // RSL-b CONVERT FROM PACKED (to long DFP) - op_CPXT uint32 = 0xEDAD // RSL-b CONVERT TO PACKED (from extended DFP) - op_CPDT uint32 = 0xEDAC // RSL-b CONVERT TO PACKED (from long DFP) - op_LZRF uint32 = 0xE33B // RXY-a LOAD AND ZERO RIGHTMOST BYTE (32) - op_LZRG uint32 = 0xE32A // RXY-a LOAD AND ZERO RIGHTMOST BYTE (64) - op_LCCB uint32 = 0xE727 // RXE LOAD COUNT TO BLOCK BOUNDARY - op_LOCHHI uint32 = 0xEC4E // RIE-g LOAD HALFWORD HIGH IMMEDIATE ON CONDITION (32←16) - op_LOCHI uint32 = 0xEC42 // RIE-g LOAD HALFWORD IMMEDIATE ON CONDITION (32←16) - op_LOCGHI uint32 = 0xEC46 // RIE-g LOAD HALFWORD IMMEDIATE ON CONDITION (64←16) - op_LOCFH uint32 = 0xEBE0 // RSY-b LOAD HIGH ON CONDITION (32) - op_LOCFHR uint32 = 0xB9E0 // RRF-c LOAD HIGH ON CONDITION (32) - op_LLZRGF uint32 = 0xE33A // RXY-a LOAD LOGICAL AND ZERO RIGHTMOST BYTE (64←32) - op_STOCFH uint32 = 0xEBE1 // RSY-b STORE HIGH ON CONDITION - op_VA uint32 = 0xE7F3 // VRR-c VECTOR ADD - op_VACC uint32 = 0xE7F1 // VRR-c VECTOR ADD COMPUTE CARRY - op_VAC uint32 = 0xE7BB // VRR-d VECTOR ADD WITH CARRY - op_VACCC uint32 = 0xE7B9 // VRR-d VECTOR ADD WITH CARRY COMPUTE CARRY - op_VN uint32 = 0xE768 // VRR-c VECTOR AND - op_VNC uint32 = 0xE769 // VRR-c VECTOR AND WITH COMPLEMENT - op_VAVG uint32 = 0xE7F2 // VRR-c VECTOR AVERAGE - op_VAVGL uint32 = 0xE7F0 // VRR-c VECTOR AVERAGE LOGICAL - op_VCKSM uint32 = 0xE766 // VRR-c VECTOR CHECKSUM - op_VCEQ uint32 = 0xE7F8 // VRR-b VECTOR COMPARE EQUAL - op_VCH uint32 = 0xE7FB // VRR-b VECTOR COMPARE HIGH - op_VCHL uint32 = 0xE7F9 // VRR-b VECTOR COMPARE HIGH LOGICAL - op_VCLZ uint32 = 0xE753 // VRR-a VECTOR COUNT LEADING ZEROS - op_VCTZ uint32 = 0xE752 // VRR-a VECTOR COUNT TRAILING ZEROS - op_VEC uint32 = 0xE7DB // VRR-a VECTOR ELEMENT COMPARE - op_VECL uint32 = 0xE7D9 // VRR-a VECTOR ELEMENT COMPARE LOGICAL - op_VERIM uint32 = 0xE772 // VRI-d VECTOR ELEMENT ROTATE AND INSERT UNDER MASK - op_VERLL uint32 = 0xE733 // VRS-a VECTOR ELEMENT ROTATE LEFT LOGICAL - op_VERLLV uint32 = 0xE773 // VRR-c VECTOR ELEMENT ROTATE LEFT LOGICAL - op_VESLV uint32 = 0xE770 // VRR-c VECTOR ELEMENT SHIFT LEFT - op_VESL uint32 = 0xE730 // VRS-a VECTOR ELEMENT SHIFT LEFT - op_VESRA uint32 = 0xE73A // VRS-a VECTOR ELEMENT SHIFT RIGHT ARITHMETIC - op_VESRAV uint32 = 0xE77A // VRR-c VECTOR ELEMENT SHIFT RIGHT ARITHMETIC - op_VESRL uint32 = 0xE738 // VRS-a VECTOR ELEMENT SHIFT RIGHT LOGICAL - op_VESRLV uint32 = 0xE778 // VRR-c VECTOR ELEMENT SHIFT RIGHT LOGICAL - op_VX uint32 = 0xE76D // VRR-c VECTOR EXCLUSIVE OR - op_VFAE uint32 = 0xE782 // VRR-b VECTOR FIND ANY ELEMENT EQUAL - op_VFEE uint32 = 0xE780 // VRR-b VECTOR FIND ELEMENT EQUAL - op_VFENE uint32 = 0xE781 // VRR-b VECTOR FIND ELEMENT NOT EQUAL - op_VFA uint32 = 0xE7E3 // VRR-c VECTOR FP ADD - op_WFK uint32 = 0xE7CA // VRR-a VECTOR FP COMPARE AND SIGNAL SCALAR - op_VFCE uint32 = 0xE7E8 // VRR-c VECTOR FP COMPARE EQUAL - op_VFCH uint32 = 0xE7EB // VRR-c VECTOR FP COMPARE HIGH - op_VFCHE uint32 = 0xE7EA // VRR-c VECTOR FP COMPARE HIGH OR EQUAL - op_WFC uint32 = 0xE7CB // VRR-a VECTOR FP COMPARE SCALAR - op_VCDG uint32 = 0xE7C3 // VRR-a VECTOR FP CONVERT FROM FIXED 64-BIT - op_VCDLG uint32 = 0xE7C1 // VRR-a VECTOR FP CONVERT FROM LOGICAL 64-BIT - op_VCGD uint32 = 0xE7C2 // VRR-a VECTOR FP CONVERT TO FIXED 64-BIT - op_VCLGD uint32 = 0xE7C0 // VRR-a VECTOR FP CONVERT TO LOGICAL 64-BIT - op_VFD uint32 = 0xE7E5 // VRR-c VECTOR FP DIVIDE - op_VLDE uint32 = 0xE7C4 // VRR-a VECTOR FP LOAD LENGTHENED - op_VLED uint32 = 0xE7C5 // VRR-a VECTOR FP LOAD ROUNDED - op_VFM uint32 = 0xE7E7 // VRR-c VECTOR FP MULTIPLY - op_VFMA uint32 = 0xE78F // VRR-e VECTOR FP MULTIPLY AND ADD - op_VFMS uint32 = 0xE78E // VRR-e VECTOR FP MULTIPLY AND SUBTRACT - op_VFPSO uint32 = 0xE7CC // VRR-a VECTOR FP PERFORM SIGN OPERATION - op_VFSQ uint32 = 0xE7CE // VRR-a VECTOR FP SQUARE ROOT - op_VFS uint32 = 0xE7E2 // VRR-c VECTOR FP SUBTRACT - op_VFTCI uint32 = 0xE74A // VRI-e VECTOR FP TEST DATA CLASS IMMEDIATE - op_VGFM uint32 = 0xE7B4 // VRR-c VECTOR GALOIS FIELD MULTIPLY SUM - op_VGFMA uint32 = 0xE7BC // VRR-d VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE - op_VGEF uint32 = 0xE713 // VRV VECTOR GATHER ELEMENT (32) - op_VGEG uint32 = 0xE712 // VRV VECTOR GATHER ELEMENT (64) - op_VGBM uint32 = 0xE744 // VRI-a VECTOR GENERATE BYTE MASK - op_VGM uint32 = 0xE746 // VRI-b VECTOR GENERATE MASK - op_VISTR uint32 = 0xE75C // VRR-a VECTOR ISOLATE STRING - op_VL uint32 = 0xE706 // VRX VECTOR LOAD - op_VLR uint32 = 0xE756 // VRR-a VECTOR LOAD - op_VLREP uint32 = 0xE705 // VRX VECTOR LOAD AND REPLICATE - op_VLC uint32 = 0xE7DE // VRR-a VECTOR LOAD COMPLEMENT - op_VLEH uint32 = 0xE701 // VRX VECTOR LOAD ELEMENT (16) - op_VLEF uint32 = 0xE703 // VRX VECTOR LOAD ELEMENT (32) - op_VLEG uint32 = 0xE702 // VRX VECTOR LOAD ELEMENT (64) - op_VLEB uint32 = 0xE700 // VRX VECTOR LOAD ELEMENT (8) - op_VLEIH uint32 = 0xE741 // VRI-a VECTOR LOAD ELEMENT IMMEDIATE (16) - op_VLEIF uint32 = 0xE743 // VRI-a VECTOR LOAD ELEMENT IMMEDIATE (32) - op_VLEIG uint32 = 0xE742 // VRI-a VECTOR LOAD ELEMENT IMMEDIATE (64) - op_VLEIB uint32 = 0xE740 // VRI-a VECTOR LOAD ELEMENT IMMEDIATE (8) - op_VFI uint32 = 0xE7C7 // VRR-a VECTOR LOAD FP INTEGER - op_VLGV uint32 = 0xE721 // VRS-c VECTOR LOAD GR FROM VR ELEMENT - op_VLLEZ uint32 = 0xE704 // VRX VECTOR LOAD LOGICAL ELEMENT AND ZERO - op_VLM uint32 = 0xE736 // VRS-a VECTOR LOAD MULTIPLE - op_VLP uint32 = 0xE7DF // VRR-a VECTOR LOAD POSITIVE - op_VLBB uint32 = 0xE707 // VRX VECTOR LOAD TO BLOCK BOUNDARY - op_VLVG uint32 = 0xE722 // VRS-b VECTOR LOAD VR ELEMENT FROM GR - op_VLVGP uint32 = 0xE762 // VRR-f VECTOR LOAD VR FROM GRS DISJOINT - op_VLL uint32 = 0xE737 // VRS-b VECTOR LOAD WITH LENGTH - op_VMX uint32 = 0xE7FF // VRR-c VECTOR MAXIMUM - op_VMXL uint32 = 0xE7FD // VRR-c VECTOR MAXIMUM LOGICAL - op_VMRH uint32 = 0xE761 // VRR-c VECTOR MERGE HIGH - op_VMRL uint32 = 0xE760 // VRR-c VECTOR MERGE LOW - op_VMN uint32 = 0xE7FE // VRR-c VECTOR MINIMUM - op_VMNL uint32 = 0xE7FC // VRR-c VECTOR MINIMUM LOGICAL - op_VMAE uint32 = 0xE7AE // VRR-d VECTOR MULTIPLY AND ADD EVEN - op_VMAH uint32 = 0xE7AB // VRR-d VECTOR MULTIPLY AND ADD HIGH - op_VMALE uint32 = 0xE7AC // VRR-d VECTOR MULTIPLY AND ADD LOGICAL EVEN - op_VMALH uint32 = 0xE7A9 // VRR-d VECTOR MULTIPLY AND ADD LOGICAL HIGH - op_VMALO uint32 = 0xE7AD // VRR-d VECTOR MULTIPLY AND ADD LOGICAL ODD - op_VMAL uint32 = 0xE7AA // VRR-d VECTOR MULTIPLY AND ADD LOW - op_VMAO uint32 = 0xE7AF // VRR-d VECTOR MULTIPLY AND ADD ODD - op_VME uint32 = 0xE7A6 // VRR-c VECTOR MULTIPLY EVEN - op_VMH uint32 = 0xE7A3 // VRR-c VECTOR MULTIPLY HIGH - op_VMLE uint32 = 0xE7A4 // VRR-c VECTOR MULTIPLY EVEN LOGICAL - op_VMLH uint32 = 0xE7A1 // VRR-c VECTOR MULTIPLY HIGH LOGICAL - op_VMLO uint32 = 0xE7A5 // VRR-c VECTOR MULTIPLY ODD LOGICAL - op_VML uint32 = 0xE7A2 // VRR-c VECTOR MULTIPLY LOW - op_VMO uint32 = 0xE7A7 // VRR-c VECTOR MULTIPLY ODD - op_VNO uint32 = 0xE76B // VRR-c VECTOR NOR - op_VO uint32 = 0xE76A // VRR-c VECTOR OR - op_VPK uint32 = 0xE794 // VRR-c VECTOR PACK - op_VPKLS uint32 = 0xE795 // VRR-b VECTOR PACK LOGICAL SATURATE - op_VPKS uint32 = 0xE797 // VRR-b VECTOR PACK SATURATE - op_VPERM uint32 = 0xE78C // VRR-e VECTOR PERMUTE - op_VPDI uint32 = 0xE784 // VRR-c VECTOR PERMUTE DOUBLEWORD IMMEDIATE - op_VPOPCT uint32 = 0xE750 // VRR-a VECTOR POPULATION COUNT - op_VREP uint32 = 0xE74D // VRI-c VECTOR REPLICATE - op_VREPI uint32 = 0xE745 // VRI-a VECTOR REPLICATE IMMEDIATE - op_VSCEF uint32 = 0xE71B // VRV VECTOR SCATTER ELEMENT (32) - op_VSCEG uint32 = 0xE71A // VRV VECTOR SCATTER ELEMENT (64) - op_VSEL uint32 = 0xE78D // VRR-e VECTOR SELECT - op_VSL uint32 = 0xE774 // VRR-c VECTOR SHIFT LEFT - op_VSLB uint32 = 0xE775 // VRR-c VECTOR SHIFT LEFT BY BYTE - op_VSLDB uint32 = 0xE777 // VRI-d VECTOR SHIFT LEFT DOUBLE BY BYTE - op_VSRA uint32 = 0xE77E // VRR-c VECTOR SHIFT RIGHT ARITHMETIC - op_VSRAB uint32 = 0xE77F // VRR-c VECTOR SHIFT RIGHT ARITHMETIC BY BYTE - op_VSRL uint32 = 0xE77C // VRR-c VECTOR SHIFT RIGHT LOGICAL - op_VSRLB uint32 = 0xE77D // VRR-c VECTOR SHIFT RIGHT LOGICAL BY BYTE - op_VSEG uint32 = 0xE75F // VRR-a VECTOR SIGN EXTEND TO DOUBLEWORD - op_VST uint32 = 0xE70E // VRX VECTOR STORE - op_VSTEH uint32 = 0xE709 // VRX VECTOR STORE ELEMENT (16) - op_VSTEF uint32 = 0xE70B // VRX VECTOR STORE ELEMENT (32) - op_VSTEG uint32 = 0xE70A // VRX VECTOR STORE ELEMENT (64) - op_VSTEB uint32 = 0xE708 // VRX VECTOR STORE ELEMENT (8) - op_VSTM uint32 = 0xE73E // VRS-a VECTOR STORE MULTIPLE - op_VSTL uint32 = 0xE73F // VRS-b VECTOR STORE WITH LENGTH - op_VSTRC uint32 = 0xE78A // VRR-d VECTOR STRING RANGE COMPARE - op_VS uint32 = 0xE7F7 // VRR-c VECTOR SUBTRACT - op_VSCBI uint32 = 0xE7F5 // VRR-c VECTOR SUBTRACT COMPUTE BORROW INDICATION - op_VSBCBI uint32 = 0xE7BD // VRR-d VECTOR SUBTRACT WITH BORROW COMPUTE BORROW INDICATION - op_VSBI uint32 = 0xE7BF // VRR-d VECTOR SUBTRACT WITH BORROW INDICATION - op_VSUMG uint32 = 0xE765 // VRR-c VECTOR SUM ACROSS DOUBLEWORD - op_VSUMQ uint32 = 0xE767 // VRR-c VECTOR SUM ACROSS QUADWORD - op_VSUM uint32 = 0xE764 // VRR-c VECTOR SUM ACROSS WORD - op_VTM uint32 = 0xE7D8 // VRR-a VECTOR TEST UNDER MASK - op_VUPH uint32 = 0xE7D7 // VRR-a VECTOR UNPACK HIGH - op_VUPLH uint32 = 0xE7D5 // VRR-a VECTOR UNPACK LOGICAL HIGH - op_VUPLL uint32 = 0xE7D4 // VRR-a VECTOR UNPACK LOGICAL LOW - op_VUPL uint32 = 0xE7D6 // VRR-a VECTOR UNPACK LOW -) - -func oclass(a *obj.Addr) int { - return int(a.Class) - 1 -} - -// Add a relocation for the immediate in a RIL style instruction. -// The addend will be adjusted as required. -func addrilreloc(ctxt *obj.Link, sym *obj.LSym, add int64) *obj.Reloc { - if sym == nil { - ctxt.Diag("require symbol to apply relocation") - } - offset := int64(2) // relocation offset from start of instruction - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + offset) - rel.Siz = 4 - rel.Sym = sym - rel.Add = add + offset + int64(rel.Siz) - rel.Type = obj.R_PCRELDBL - return rel -} - -func addrilrelocoffset(ctxt *obj.Link, sym *obj.LSym, add, offset int64) *obj.Reloc { - if sym == nil { - ctxt.Diag("require symbol to apply relocation") - } - offset += int64(2) // relocation offset from start of instruction - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + offset) - rel.Siz = 4 - rel.Sym = sym - rel.Add = add + offset + int64(rel.Siz) - rel.Type = obj.R_PCRELDBL - return rel -} - -// Add a CALL relocation for the immediate in a RIL style instruction. -// The addend will be adjusted as required. -func addcallreloc(ctxt *obj.Link, sym *obj.LSym, add int64) *obj.Reloc { - if sym == nil { - ctxt.Diag("require symbol to apply relocation") - } - offset := int64(2) // relocation offset from start of instruction - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + offset) - rel.Siz = 4 - rel.Sym = sym - rel.Add = add + offset + int64(rel.Siz) - rel.Type = obj.R_CALL - return rel -} - -func branchMask(ctxt *obj.Link, p *obj.Prog) uint32 { - switch p.As { - case ABEQ, ACMPBEQ, ACMPUBEQ, AMOVDEQ: - return 0x8 - case ABGE, ACMPBGE, ACMPUBGE, AMOVDGE: - return 0xA - case ABGT, ACMPBGT, ACMPUBGT, AMOVDGT: - return 0x2 - case ABLE, ACMPBLE, ACMPUBLE, AMOVDLE: - return 0xC - case ABLT, ACMPBLT, ACMPUBLT, AMOVDLT: - return 0x4 - case ABNE, ACMPBNE, ACMPUBNE, AMOVDNE: - return 0x7 - case ABLEU: // LE or unordered - return 0xD - case ABLTU: // LT or unordered - return 0x5 - case ABVC: - return 0x0 // needs extra instruction - case ABVS: - return 0x1 // unordered - } - ctxt.Diag("unknown conditional branch %v", p.As) - return 0xF -} - -func asmout(ctxt *obj.Link, asm *[]byte) { - p := ctxt.Curp - o := oplook(ctxt, p) - ctxt.Printp = p - - switch o.type_ { - default: - ctxt.Diag("unknown type %d", o.type_) - - case 0: // PSEUDO OPS - break - - case 1: // mov reg reg - switch p.As { - default: - ctxt.Diag("unhandled operation: %v", p.As) - case AMOVD: - zRRE(op_LGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - // sign extend - case AMOVW: - zRRE(op_LGFR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - case AMOVH: - zRRE(op_LGHR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - case AMOVB: - zRRE(op_LGBR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - // zero extend - case AMOVWZ: - zRRE(op_LLGFR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - case AMOVHZ: - zRRE(op_LLGHR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - case AMOVBZ: - zRRE(op_LLGCR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - // reverse bytes - case AMOVDBR: - zRRE(op_LRVGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - case AMOVWBR: - zRRE(op_LRVR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - // floating point - case AFMOVD, AFMOVS: - zRR(op_LDR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - - case 2: // arithmetic op reg [reg] reg - r := p.Reg - if r == 0 { - r = p.To.Reg - } - - var opcode uint32 - - switch p.As { - default: - ctxt.Diag("invalid opcode") - case AADD: - opcode = op_AGRK - case AADDC: - opcode = op_ALGRK - case AADDE: - opcode = op_ALCGR - case AADDW: - opcode = op_ARK - case AMULLW: - opcode = op_MSGFR - case AMULLD: - opcode = op_MSGR - case ADIVW, AMODW: - opcode = op_DSGFR - case ADIVWU, AMODWU: - opcode = op_DLR - case ADIVD, AMODD: - opcode = op_DSGR - case ADIVDU, AMODDU: - opcode = op_DLGR - case AFADD: - opcode = op_ADBR - case AFADDS: - opcode = op_AEBR - case AFSUB: - opcode = op_SDBR - case AFSUBS: - opcode = op_SEBR - case AFDIV: - opcode = op_DDBR - case AFDIVS: - opcode = op_DEBR - } - - switch p.As { - default: - - case AADD, AADDC, AADDW: - if p.As == AADDW && r == p.To.Reg { - zRR(op_AR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else { - zRRF(opcode, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm) - } - - case AADDE, AMULLW, AMULLD: - if r == p.To.Reg { - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else if p.From.Reg == p.To.Reg { - zRRE(opcode, uint32(p.To.Reg), uint32(r), asm) - } else { - zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm) - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - - case ADIVW, ADIVWU, ADIVD, ADIVDU: - if p.As == ADIVWU || p.As == ADIVDU { - zRI(op_LGHI, REGTMP, 0, asm) - } - zRRE(op_LGR, REGTMP2, uint32(r), asm) - zRRE(opcode, REGTMP, uint32(p.From.Reg), asm) - zRRE(op_LGR, uint32(p.To.Reg), REGTMP2, asm) - - case AMODW, AMODWU, AMODD, AMODDU: - if p.As == AMODWU || p.As == AMODDU { - zRI(op_LGHI, REGTMP, 0, asm) - } - zRRE(op_LGR, REGTMP2, uint32(r), asm) - zRRE(opcode, REGTMP, uint32(p.From.Reg), asm) - zRRE(op_LGR, uint32(p.To.Reg), REGTMP, asm) - - case AFADD, AFADDS: - if r == p.To.Reg { - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else if p.From.Reg == p.To.Reg { - zRRE(opcode, uint32(p.To.Reg), uint32(r), asm) - } else { - zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm) - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - - case AFSUB, AFSUBS, AFDIV, AFDIVS: - if r == p.To.Reg { - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else if p.From.Reg == p.To.Reg { - zRRE(op_LGDR, REGTMP, uint32(r), asm) - zRRE(opcode, uint32(r), uint32(p.From.Reg), asm) - zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm) - zRRE(op_LDGR, uint32(r), REGTMP, asm) - } else { - zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm) - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - - } - - case 3: // mov $constant reg - v := vregoff(ctxt, &p.From) - switch p.As { - case AMOVBZ: - v = int64(uint8(v)) - case AMOVHZ: - v = int64(uint16(v)) - case AMOVWZ: - v = int64(uint32(v)) - case AMOVB: - v = int64(int8(v)) - case AMOVH: - v = int64(int16(v)) - case AMOVW: - v = int64(int32(v)) - } - if int64(int16(v)) == v { - zRI(op_LGHI, uint32(p.To.Reg), uint32(v), asm) - } else if v&0xffff0000 == v { - zRI(op_LLILH, uint32(p.To.Reg), uint32(v>>16), asm) - } else if v&0xffff00000000 == v { - zRI(op_LLIHL, uint32(p.To.Reg), uint32(v>>32), asm) - } else if uint64(v)&0xffff000000000000 == uint64(v) { - zRI(op_LLIHH, uint32(p.To.Reg), uint32(v>>48), asm) - } else if int64(int32(v)) == v { - zRIL(_a, op_LGFI, uint32(p.To.Reg), uint32(v), asm) - } else if int64(uint32(v)) == v { - zRIL(_a, op_LLILF, uint32(p.To.Reg), uint32(v), asm) - } else if uint64(v)&0xffffffff00000000 == uint64(v) { - zRIL(_a, op_LLIHF, uint32(p.To.Reg), uint32(v>>32), asm) - } else { - zRIL(_a, op_LLILF, uint32(p.To.Reg), uint32(v), asm) - zRIL(_a, op_IIHF, uint32(p.To.Reg), uint32(v>>32), asm) - } - - case 4: // multiply high (a*b)>>64 - r := p.Reg - if r == 0 { - r = p.To.Reg - } - zRRE(op_LGR, REGTMP2, uint32(r), asm) - zRRE(op_MLGR, REGTMP, uint32(p.From.Reg), asm) - switch p.As { - case AMULHDU: - // Unsigned: move result into correct register. - zRRE(op_LGR, uint32(p.To.Reg), REGTMP, asm) - case AMULHD: - // Signed: need to convert result. - // See Hacker's Delight 8-3. - zRSY(op_SRAG, REGTMP2, uint32(p.From.Reg), 0, 63, asm) - zRRE(op_NGR, REGTMP2, uint32(r), asm) - zRRE(op_SGR, REGTMP, REGTMP2, asm) - zRSY(op_SRAG, REGTMP2, uint32(r), 0, 63, asm) - zRRE(op_NGR, REGTMP2, uint32(p.From.Reg), asm) - zRRF(op_SGRK, REGTMP2, 0, uint32(p.To.Reg), REGTMP, asm) - } - - case 5: // syscall - zI(op_SVC, 0, asm) - - case 6: // logical op reg [reg] reg - var oprr, oprre, oprrf uint32 - switch p.As { - case AAND: - oprre = op_NGR - oprrf = op_NGRK - case AANDW: - oprr = op_NR - oprrf = op_NRK - case AOR: - oprre = op_OGR - oprrf = op_OGRK - case AORW: - oprr = op_OR - oprrf = op_ORK - case AXOR: - oprre = op_XGR - oprrf = op_XGRK - case AXORW: - oprr = op_XR - oprrf = op_XRK - } - if p.Reg == 0 { - if oprr != 0 { - zRR(oprr, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else { - zRRE(oprre, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - } else { - zRRF(oprrf, uint32(p.Reg), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - - case 7: // shift/rotate reg [reg] reg - d2 := vregoff(ctxt, &p.From) - b2 := p.From.Reg - r3 := p.Reg - if r3 == 0 { - r3 = p.To.Reg - } - r1 := p.To.Reg - var opcode uint32 - switch p.As { - default: - case ASLD: - opcode = op_SLLG - case ASRD: - opcode = op_SRLG - case ASLW: - opcode = op_SLLK - case ASRW: - opcode = op_SRLK - case ARLL: - opcode = op_RLL - case ARLLG: - opcode = op_RLLG - case ASRAW: - opcode = op_SRAK - case ASRAD: - opcode = op_SRAG - } - zRSY(opcode, uint32(r1), uint32(r3), uint32(b2), uint32(d2), asm) - - case 8: // find leftmost one - if p.To.Reg&1 != 0 { - ctxt.Diag("target must be an even-numbered register") - } - // FLOGR also writes a mask to p.To.Reg+1. - zRRE(op_FLOGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - - case 10: // subtract reg [reg] reg - r := int(p.Reg) - - switch p.As { - default: - case ASUB: - if r == 0 { - zRRE(op_SGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else { - zRRF(op_SGRK, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm) - } - case ASUBC: - if r == 0 { - zRRE(op_SLGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else { - zRRF(op_SLGRK, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm) - } - case ASUBE: - if r == 0 { - r = int(p.To.Reg) - } - if r == int(p.To.Reg) { - zRRE(op_SLBGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else if p.From.Reg == p.To.Reg { - zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm) - zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm) - zRRE(op_SLBGR, uint32(p.To.Reg), REGTMP, asm) - } else { - zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm) - zRRE(op_SLBGR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - case ASUBW: - if r == 0 { - zRR(op_SR, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else { - zRRF(op_SRK, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm) - } - } - - case 11: // br/bl - v := int32(0) - - if p.Pcond != nil { - v = int32((p.Pcond.Pc - p.Pc) >> 1) - } - - if p.As == ABR && p.To.Sym == nil && int32(int16(v)) == v { - zRI(op_BRC, 0xF, uint32(v), asm) - } else { - if p.As == ABL { - zRIL(_b, op_BRASL, uint32(REG_LR), uint32(v), asm) - } else { - zRIL(_c, op_BRCL, 0xF, uint32(v), asm) - } - if p.To.Sym != nil { - addcallreloc(ctxt, p.To.Sym, p.To.Offset) - } - } - - case 12: - r1 := p.To.Reg - d2 := vregoff(ctxt, &p.From) - b2 := p.From.Reg - if b2 == 0 { - b2 = o.param - } - x2 := p.From.Index - if -DISP20/2 > d2 || d2 >= DISP20/2 { - zRIL(_a, op_LGFI, REGTMP, uint32(d2), asm) - if x2 != 0 { - zRX(op_LA, REGTMP, REGTMP, uint32(x2), 0, asm) - } - x2 = REGTMP - d2 = 0 - } - var opx, opxy uint32 - switch p.As { - case AADD: - opxy = op_AG - case AADDC: - opxy = op_ALG - case AADDW: - opx = op_A - opxy = op_AY - case AMULLW: - opx = op_MS - opxy = op_MSY - case AMULLD: - opxy = op_MSG - case ASUB: - opxy = op_SG - case ASUBC: - opxy = op_SLG - case ASUBE: - opxy = op_SLBG - case ASUBW: - opx = op_S - opxy = op_SY - case AAND: - opxy = op_NG - case AANDW: - opx = op_N - opxy = op_NY - case AOR: - opxy = op_OG - case AORW: - opx = op_O - opxy = op_OY - case AXOR: - opxy = op_XG - case AXORW: - opx = op_X - opxy = op_XY - } - if opx != 0 && 0 <= d2 && d2 < DISP12 { - zRX(opx, uint32(r1), uint32(x2), uint32(b2), uint32(d2), asm) - } else { - zRXY(opxy, uint32(r1), uint32(x2), uint32(b2), uint32(d2), asm) - } - - case 15: // br/bl (reg) - r := p.To.Reg - if p.As == ABCL || p.As == ABL { - zRR(op_BASR, uint32(REG_LR), uint32(r), asm) - } else { - zRR(op_BCR, 0xF, uint32(r), asm) - } - - case 16: // conditional branch - v := int32(0) - if p.Pcond != nil { - v = int32((p.Pcond.Pc - p.Pc) >> 1) - } - mask := branchMask(ctxt, p) - if p.To.Sym == nil && int32(int16(v)) == v { - zRI(op_BRC, mask, uint32(v), asm) - } else { - zRIL(_c, op_BRCL, mask, uint32(v), asm) - } - if p.To.Sym != nil { - addrilreloc(ctxt, p.To.Sym, p.To.Offset) - } - - case 17: // move on condition - m3 := branchMask(ctxt, p) - zRRF(op_LOCGR, m3, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm) - - case 18: // br/bl reg - if p.As == ABL { - zRR(op_BASR, uint32(REG_LR), uint32(p.To.Reg), asm) - } else { - zRR(op_BCR, 0xF, uint32(p.To.Reg), asm) - } - - case 19: // mov $sym+n(SB) reg - d := vregoff(ctxt, &p.From) - zRIL(_b, op_LARL, uint32(p.To.Reg), 0, asm) - if d&1 != 0 { - zRX(op_LA, uint32(p.To.Reg), uint32(p.To.Reg), 0, 1, asm) - d -= 1 - } - addrilreloc(ctxt, p.From.Sym, d) - - case 21: // subtract $constant [reg] reg - v := vregoff(ctxt, &p.From) - r := p.Reg - if r == 0 { - r = p.To.Reg - } - switch p.As { - case ASUB: - zRIL(_a, op_LGFI, uint32(REGTMP), uint32(v), asm) - zRRF(op_SLGRK, uint32(REGTMP), 0, uint32(p.To.Reg), uint32(r), asm) - case ASUBC: - if r != p.To.Reg { - zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm) - } - zRIL(_a, op_SLGFI, uint32(p.To.Reg), uint32(v), asm) - case ASUBW: - if r != p.To.Reg { - zRR(op_LR, uint32(p.To.Reg), uint32(r), asm) - } - zRIL(_a, op_SLFI, uint32(p.To.Reg), uint32(v), asm) - } - - case 22: // add/multiply $constant [reg] reg - v := vregoff(ctxt, &p.From) - r := p.Reg - if r == 0 { - r = p.To.Reg - } - var opri, opril, oprie uint32 - switch p.As { - case AADD: - opri = op_AGHI - opril = op_AGFI - oprie = op_AGHIK - case AADDC: - opril = op_ALGFI - oprie = op_ALGHSIK - case AADDW: - opri = op_AHI - opril = op_AFI - oprie = op_AHIK - case AMULLW: - opri = op_MHI - opril = op_MSFI - case AMULLD: - opri = op_MGHI - opril = op_MSGFI - } - if r != p.To.Reg && (oprie == 0 || int64(int16(v)) != v) { - switch p.As { - case AADD, AADDC, AMULLD: - zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm) - case AADDW, AMULLW: - zRR(op_LR, uint32(p.To.Reg), uint32(r), asm) - } - r = p.To.Reg - } - if r == p.To.Reg { - if opri != 0 && int64(int16(v)) == v { - zRI(opri, uint32(p.To.Reg), uint32(v), asm) - } else { - zRIL(_a, opril, uint32(p.To.Reg), uint32(v), asm) - } - } else { - zRIE(_d, oprie, uint32(p.To.Reg), uint32(r), uint32(v), 0, 0, 0, 0, asm) - } - - case 23: // 64-bit logical op $constant reg - // TODO(mundaym): merge with case 24. - v := vregoff(ctxt, &p.From) - switch p.As { - default: - ctxt.Diag("%v is not supported", p) - case AAND: - if v >= 0 { // needs zero extend - zRIL(_a, op_LGFI, REGTMP, uint32(v), asm) - zRRE(op_NGR, uint32(p.To.Reg), REGTMP, asm) - } else if int64(int16(v)) == v { - zRI(op_NILL, uint32(p.To.Reg), uint32(v), asm) - } else { // r.To.Reg & 0xffffffff00000000 & uint32(v) - zRIL(_a, op_NILF, uint32(p.To.Reg), uint32(v), asm) - } - case AOR: - if int64(uint32(v)) != v { // needs sign extend - zRIL(_a, op_LGFI, REGTMP, uint32(v), asm) - zRRE(op_OGR, uint32(p.To.Reg), REGTMP, asm) - } else if int64(uint16(v)) == v { - zRI(op_OILL, uint32(p.To.Reg), uint32(v), asm) - } else { - zRIL(_a, op_OILF, uint32(p.To.Reg), uint32(v), asm) - } - case AXOR: - if int64(uint32(v)) != v { // needs sign extend - zRIL(_a, op_LGFI, REGTMP, uint32(v), asm) - zRRE(op_XGR, uint32(p.To.Reg), REGTMP, asm) - } else { - zRIL(_a, op_XILF, uint32(p.To.Reg), uint32(v), asm) - } - } - - case 24: // 32-bit logical op $constant reg - v := vregoff(ctxt, &p.From) - switch p.As { - case AANDW: - if uint32(v&0xffff0000) == 0xffff0000 { - zRI(op_NILL, uint32(p.To.Reg), uint32(v), asm) - } else if uint32(v&0x0000ffff) == 0x0000ffff { - zRI(op_NILH, uint32(p.To.Reg), uint32(v)>>16, asm) - } else { - zRIL(_a, op_NILF, uint32(p.To.Reg), uint32(v), asm) - } - case AORW: - if uint32(v&0xffff0000) == 0 { - zRI(op_OILL, uint32(p.To.Reg), uint32(v), asm) - } else if uint32(v&0x0000ffff) == 0 { - zRI(op_OILH, uint32(p.To.Reg), uint32(v)>>16, asm) - } else { - zRIL(_a, op_OILF, uint32(p.To.Reg), uint32(v), asm) - } - case AXORW: - zRIL(_a, op_XILF, uint32(p.To.Reg), uint32(v), asm) - } - - case 26: // MOVD $offset(base)(index), reg - v := regoff(ctxt, &p.From) - r := p.From.Reg - if r == 0 { - r = o.param - } - i := p.From.Index - if v >= 0 && v < DISP12 { - zRX(op_LA, uint32(p.To.Reg), uint32(r), uint32(i), uint32(v), asm) - } else if v >= -DISP20/2 && v < DISP20/2 { - zRXY(op_LAY, uint32(p.To.Reg), uint32(r), uint32(i), uint32(v), asm) - } else { - zRIL(_a, op_LGFI, REGTMP, uint32(v), asm) - zRX(op_LA, uint32(p.To.Reg), uint32(r), REGTMP, uint32(i), asm) - } - - case 31: // dword - wd := uint64(vregoff(ctxt, &p.From)) - *asm = append(*asm, - uint8(wd>>56), - uint8(wd>>48), - uint8(wd>>40), - uint8(wd>>32), - uint8(wd>>24), - uint8(wd>>16), - uint8(wd>>8), - uint8(wd)) - - case 32: // fmul freg [freg] freg - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - - var opcode uint32 - - switch p.As { - default: - ctxt.Diag("invalid opcode") - case AFMUL: - opcode = op_MDBR - case AFMULS: - opcode = op_MEEBR - } - - if r == int(p.To.Reg) { - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } else if p.From.Reg == p.To.Reg { - zRRE(opcode, uint32(p.To.Reg), uint32(r), asm) - } else { - zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm) - zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm) - } - - case 33: // float op [freg] freg - r := p.From.Reg - if oclass(&p.From) == C_NONE { - r = p.To.Reg - } - var opcode uint32 - switch p.As { - default: - case AFABS: - opcode = op_LPDBR - case AFNABS: - opcode = op_LNDBR - case AFNEG: - opcode = op_LCDFR - case AFNEGS: - opcode = op_LCEBR - case ALEDBR: - opcode = op_LEDBR - case ALDEBR: - opcode = op_LDEBR - case AFSQRT: - opcode = op_SQDBR - case AFSQRTS: - opcode = op_SQEBR - } - zRRE(opcode, uint32(p.To.Reg), uint32(r), asm) - - case 34: // float multiply-add freg freg freg freg - var opcode uint32 - - switch p.As { - default: - ctxt.Diag("invalid opcode") - case AFMADD: - opcode = op_MADBR - case AFMADDS: - opcode = op_MAEBR - case AFMSUB: - opcode = op_MSDBR - case AFMSUBS: - opcode = op_MSEBR - case AFNMADD: - opcode = op_MADBR - case AFNMADDS: - opcode = op_MAEBR - case AFNMSUB: - opcode = op_MSDBR - case AFNMSUBS: - opcode = op_MSEBR - } - - zRR(op_LDR, uint32(p.To.Reg), uint32(p.Reg), asm) - zRRD(opcode, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From3.Reg), asm) - - if p.As == AFNMADD || p.As == AFNMADDS || p.As == AFNMSUB || p.As == AFNMSUBS { - zRRE(op_LCDFR, uint32(p.To.Reg), uint32(p.To.Reg), asm) - } - - case 35: // mov reg mem (no relocation) - d2 := regoff(ctxt, &p.To) - b2 := p.To.Reg - if b2 == 0 { - b2 = o.param - } - x2 := p.To.Index - if d2 < -DISP20/2 || d2 >= DISP20/2 { - zRIL(_a, op_LGFI, REGTMP, uint32(d2), asm) - if x2 != 0 { - zRX(op_LA, REGTMP, REGTMP, uint32(x2), 0, asm) - } - x2 = REGTMP - d2 = 0 - } - zRXY(zopstore(ctxt, p.As), uint32(p.From.Reg), uint32(x2), uint32(b2), uint32(d2), asm) - - case 36: // mov mem reg (no relocation) - d2 := regoff(ctxt, &p.From) - b2 := p.From.Reg - if b2 == 0 { - b2 = o.param - } - x2 := p.From.Index - if d2 < -DISP20/2 || d2 >= DISP20/2 { - zRIL(_a, op_LGFI, REGTMP, uint32(d2), asm) - if x2 != 0 { - zRX(op_LA, REGTMP, REGTMP, uint32(x2), 0, asm) - } - x2 = REGTMP - d2 = 0 - } - zRXY(zopload(ctxt, p.As), uint32(p.To.Reg), uint32(x2), uint32(b2), uint32(d2), asm) - - case 40: // word/byte - wd := uint32(regoff(ctxt, &p.From)) - if p.As == AWORD { //WORD - *asm = append(*asm, uint8(wd>>24), uint8(wd>>16), uint8(wd>>8), uint8(wd)) - } else { //BYTE - *asm = append(*asm, uint8(wd)) - } - - case 47: // negate [reg] reg - r := p.From.Reg - if r == 0 { - r = p.To.Reg - } - switch p.As { - case ANEG: - zRRE(op_LCGR, uint32(p.To.Reg), uint32(r), asm) - case ANEGW: - zRRE(op_LCGFR, uint32(p.To.Reg), uint32(r), asm) - } - - case 48: // floating-point round to integer - m3 := vregoff(ctxt, &p.From) - if 0 > m3 || m3 > 7 { - ctxt.Diag("mask (%v) must be in the range [0, 7]", m3) - } - var opcode uint32 - switch p.As { - case AFIEBR: - opcode = op_FIEBR - case AFIDBR: - opcode = op_FIDBR - } - zRRF(opcode, uint32(m3), 0, uint32(p.To.Reg), uint32(p.Reg), asm) - - case 67: // fmov $0 freg - var opcode uint32 - switch p.As { - case AFMOVS: - opcode = op_LZER - case AFMOVD: - opcode = op_LZDR - } - zRRE(opcode, uint32(p.To.Reg), 0, asm) - - case 68: // movw areg reg - zRRE(op_EAR, uint32(p.To.Reg), uint32(p.From.Reg-REG_AR0), asm) - - case 69: // movw reg areg - zRRE(op_SAR, uint32(p.To.Reg-REG_AR0), uint32(p.From.Reg), asm) - - case 70: // cmp reg reg - if p.As == ACMPW || p.As == ACMPWU { - zRR(zoprr(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), asm) - } else { - zRRE(zoprre(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), asm) - } - - case 71: // cmp reg $constant - v := vregoff(ctxt, &p.To) - switch p.As { - case ACMP, ACMPW: - if int64(int32(v)) != v { - ctxt.Diag("%v overflows an int32", v) - } - case ACMPU, ACMPWU: - if int64(uint32(v)) != v { - ctxt.Diag("%v overflows a uint32", v) - } - } - if p.As == ACMP && int64(int16(v)) == v { - zRI(op_CGHI, uint32(p.From.Reg), uint32(v), asm) - } else if p.As == ACMPW && int64(int16(v)) == v { - zRI(op_CHI, uint32(p.From.Reg), uint32(v), asm) - } else { - zRIL(_a, zopril(ctxt, p.As), uint32(p.From.Reg), uint32(v), asm) - } - - case 72: // mov $constant mem - v := regoff(ctxt, &p.From) - d := regoff(ctxt, &p.To) - r := p.To.Reg - x := p.To.Index - if r == 0 { - r = o.param - } - if int32(int16(v)) == v && x == 0 { - if d < 0 || d >= DISP12 { - if r == REGTMP || r == REGTMP2 { - zRIL(_a, op_AGFI, uint32(r), uint32(d), asm) - } else { - zRIL(_a, op_LGFI, REGTMP, uint32(d), asm) - zRRE(op_AGR, REGTMP, uint32(r), asm) - r = REGTMP - } - d = 0 - } - var opcode uint32 - switch p.As { - case AMOVD: - opcode = op_MVGHI - case AMOVW, AMOVWZ: - opcode = op_MVHI - case AMOVH, AMOVHZ: - opcode = op_MVHHI - case AMOVB, AMOVBZ: - opcode = op_MVI - } - if opcode == op_MVI { - zSI(opcode, uint32(v), uint32(r), uint32(d), asm) - } else { - zSIL(opcode, uint32(r), uint32(d), uint32(v), asm) - } - } else { - zRIL(_a, op_LGFI, REGTMP2, uint32(v), asm) - if d < -DISP20/2 || d >= DISP20/2 { - if r == REGTMP { - zRIL(_a, op_AGFI, REGTMP, uint32(d), asm) - } else { - zRIL(_a, op_LGFI, REGTMP, uint32(d), asm) - if x != 0 { - zRRE(op_AGR, REGTMP, uint32(x), asm) - } - x = REGTMP - } - d = 0 - } - zRXY(zopstore(ctxt, p.As), REGTMP2, uint32(x), uint32(r), uint32(d), asm) - } - - case 73: // mov $constant addr (including relocation) - v := regoff(ctxt, &p.From) - d := regoff(ctxt, &p.To) - a := uint32(0) - if d&1 != 0 { - d -= 1 - a = 1 - } - zRIL(_b, op_LARL, REGTMP, uint32(d), asm) - addrilreloc(ctxt, p.To.Sym, int64(d)) - if int32(int16(v)) == v { - var opcode uint32 - switch p.As { - case AMOVD: - opcode = op_MVGHI - case AMOVW, AMOVWZ: - opcode = op_MVHI - case AMOVH, AMOVHZ: - opcode = op_MVHHI - case AMOVB, AMOVBZ: - opcode = op_MVI - } - if opcode == op_MVI { - zSI(opcode, uint32(v), REGTMP, a, asm) - } else { - zSIL(opcode, REGTMP, a, uint32(v), asm) - } - } else { - zRIL(_a, op_LGFI, REGTMP2, uint32(v), asm) - zRXY(zopstore(ctxt, p.As), REGTMP2, 0, REGTMP, a, asm) - } - - case 74: // mov reg addr (including relocation) - i2 := regoff(ctxt, &p.To) - switch p.As { - case AMOVD: - zRIL(_b, op_STGRL, uint32(p.From.Reg), 0, asm) - case AMOVW, AMOVWZ: // The zero extension doesn't affect store instructions - zRIL(_b, op_STRL, uint32(p.From.Reg), 0, asm) - case AMOVH, AMOVHZ: // The zero extension doesn't affect store instructions - zRIL(_b, op_STHRL, uint32(p.From.Reg), 0, asm) - case AMOVB, AMOVBZ: // The zero extension doesn't affect store instructions - zRIL(_b, op_LARL, REGTMP, 0, asm) - adj := uint32(0) // adjustment needed for odd addresses - if i2&1 != 0 { - i2 -= 1 - adj = 1 - } - zRX(op_STC, uint32(p.From.Reg), 0, REGTMP, adj, asm) - case AFMOVD: - zRIL(_b, op_LARL, REGTMP, 0, asm) - zRX(op_STD, uint32(p.From.Reg), 0, REGTMP, 0, asm) - case AFMOVS: - zRIL(_b, op_LARL, REGTMP, 0, asm) - zRX(op_STE, uint32(p.From.Reg), 0, REGTMP, 0, asm) - } - addrilreloc(ctxt, p.To.Sym, int64(i2)) - - case 75: // mov addr reg (including relocation) - i2 := regoff(ctxt, &p.From) - switch p.As { - case AMOVD: - if i2&1 != 0 { - zRIL(_b, op_LARL, REGTMP, 0, asm) - zRXY(op_LG, uint32(p.To.Reg), REGTMP, 0, 1, asm) - i2 -= 1 - } else { - zRIL(_b, op_LGRL, uint32(p.To.Reg), 0, asm) - } - case AMOVW: - zRIL(_b, op_LGFRL, uint32(p.To.Reg), 0, asm) - case AMOVWZ: - zRIL(_b, op_LLGFRL, uint32(p.To.Reg), 0, asm) - case AMOVH: - zRIL(_b, op_LGHRL, uint32(p.To.Reg), 0, asm) - case AMOVHZ: - zRIL(_b, op_LLGHRL, uint32(p.To.Reg), 0, asm) - case AMOVB, AMOVBZ: - zRIL(_b, op_LARL, REGTMP, 0, asm) - adj := uint32(0) // adjustment needed for odd addresses - if i2&1 != 0 { - i2 -= 1 - adj = 1 - } - switch p.As { - case AMOVB: - zRXY(op_LGB, uint32(p.To.Reg), 0, REGTMP, adj, asm) - case AMOVBZ: - zRXY(op_LLGC, uint32(p.To.Reg), 0, REGTMP, adj, asm) - } - case AFMOVD: - zRIL(_a, op_LARL, REGTMP, 0, asm) - zRX(op_LD, uint32(p.To.Reg), 0, REGTMP, 0, asm) - case AFMOVS: - zRIL(_a, op_LARL, REGTMP, 0, asm) - zRX(op_LE, uint32(p.To.Reg), 0, REGTMP, 0, asm) - } - addrilreloc(ctxt, p.From.Sym, int64(i2)) - - case 77: // syscall $constant - if p.From.Offset > 255 || p.From.Offset < 1 { - ctxt.Diag("illegal system call; system call number out of range: %v", p) - zE(op_TRAP2, asm) // trap always - } else { - zI(op_SVC, uint32(p.From.Offset), asm) - } - - case 78: // undef - // "An instruction consisting entirely of binary 0s is guaranteed - // always to be an illegal instruction." - *asm = append(*asm, 0, 0, 0, 0) - - case 79: // compare and swap reg reg reg - v := regoff(ctxt, &p.To) - if v < 0 { - v = 0 - } - if p.As == ACS { - zRS(op_CS, uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg), uint32(v), asm) - } else if p.As == ACSG { - zRSY(op_CSG, uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg), uint32(v), asm) - } - - case 81: // sync - zRR(op_BCR, 0xE, 0, asm) - - case 82: // fixed to float conversion - var opcode uint32 - switch p.As { - default: - log.Fatalf("unexpected opcode %v", p.As) - case ACEFBRA: - opcode = op_CEFBRA - case ACDFBRA: - opcode = op_CDFBRA - case ACEGBRA: - opcode = op_CEGBRA - case ACDGBRA: - opcode = op_CDGBRA - case ACELFBR: - opcode = op_CELFBR - case ACDLFBR: - opcode = op_CDLFBR - case ACELGBR: - opcode = op_CELGBR - case ACDLGBR: - opcode = op_CDLGBR - } - // set immediate operand M3 to 0 to use the default BFP rounding mode - // (usually round to nearest, ties to even) - // TODO(mundaym): should this be fixed at round to nearest, ties to even? - // M4 is reserved and must be 0 - zRRF(opcode, 0, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm) - - case 83: // float to fixed conversion - var opcode uint32 - switch p.As { - default: - log.Fatalf("unexpected opcode %v", p.As) - case ACFEBRA: - opcode = op_CFEBRA - case ACFDBRA: - opcode = op_CFDBRA - case ACGEBRA: - opcode = op_CGEBRA - case ACGDBRA: - opcode = op_CGDBRA - case ACLFEBR: - opcode = op_CLFEBR - case ACLFDBR: - opcode = op_CLFDBR - case ACLGEBR: - opcode = op_CLGEBR - case ACLGDBR: - opcode = op_CLGDBR - } - // set immediate operand M3 to 5 for rounding toward zero (required by Go spec) - // M4 is reserved and must be 0 - zRRF(opcode, 5, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm) - - case 84: // storage-and-storage operations $length mem mem (length in From3) - l := regoff(ctxt, p.From3) - if l < 1 || l > 256 { - ctxt.Diag("number of bytes (%v) not in range [1,256]", l) - } - if p.From.Index != 0 || p.To.Index != 0 { - ctxt.Diag("cannot use index reg") - } - b1 := p.To.Reg - b2 := p.From.Reg - if b1 == 0 { - b1 = o.param - } - if b2 == 0 { - b2 = o.param - } - d1 := regoff(ctxt, &p.To) - d2 := regoff(ctxt, &p.From) - if d1 < 0 || d1 >= DISP12 { - if b2 == REGTMP { - ctxt.Diag("REGTMP conflict") - } - if b1 != REGTMP { - zRRE(op_LGR, REGTMP, uint32(b1), asm) - } - zRIL(_a, op_AGFI, REGTMP, uint32(d1), asm) - if d1 == d2 && b1 == b2 { - d2 = 0 - b2 = REGTMP - } - d1 = 0 - b1 = REGTMP - } - if d2 < 0 || d2 >= DISP12 { - if b1 == REGTMP2 { - ctxt.Diag("REGTMP2 conflict") - } - if b2 != REGTMP2 { - zRRE(op_LGR, REGTMP2, uint32(b2), asm) - } - zRIL(_a, op_AGFI, REGTMP2, uint32(d2), asm) - d2 = 0 - b2 = REGTMP2 - } - var opcode uint32 - switch p.As { - default: - ctxt.Diag("unexpected opcode %v", p.As) - case AMVC: - opcode = op_MVC - case ACLC: - opcode = op_CLC - // swap operand order for CLC so that it matches CMP - b1, b2 = b2, b1 - d1, d2 = d2, d1 - case AXC: - opcode = op_XC - case AOC: - opcode = op_OC - case ANC: - opcode = op_NC - } - zSS(_a, opcode, uint32(l-1), 0, uint32(b1), uint32(d1), uint32(b2), uint32(d2), asm) - - case 85: // load address relative long - v := regoff(ctxt, &p.From) - if p.From.Sym == nil { - if (v & 1) != 0 { - ctxt.Diag("cannot use LARL with odd offset: %v", v) - } - } else { - addrilreloc(ctxt, p.From.Sym, int64(v)) - v = 0 - } - zRIL(_b, op_LARL, uint32(p.To.Reg), uint32(v>>1), asm) - - case 86: // load address - d := vregoff(ctxt, &p.From) - x := p.From.Index - b := p.From.Reg - if b == 0 { - b = o.param - } - switch p.As { - case ALA: - zRX(op_LA, uint32(p.To.Reg), uint32(x), uint32(b), uint32(d), asm) - case ALAY: - zRXY(op_LAY, uint32(p.To.Reg), uint32(x), uint32(b), uint32(d), asm) - } - - case 87: // execute relative long - v := vregoff(ctxt, &p.From) - if p.From.Sym == nil { - if v&1 != 0 { - ctxt.Diag("cannot use EXRL with odd offset: %v", v) - } - } else { - addrilreloc(ctxt, p.From.Sym, v) - v = 0 - } - zRIL(_b, op_EXRL, uint32(p.To.Reg), uint32(v>>1), asm) - - case 88: // store clock - var opcode uint32 - switch p.As { - case ASTCK: - opcode = op_STCK - case ASTCKC: - opcode = op_STCKC - case ASTCKE: - opcode = op_STCKE - case ASTCKF: - opcode = op_STCKF - } - v := vregoff(ctxt, &p.To) - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - zS(opcode, uint32(r), uint32(v), asm) - - case 89: // compare and branch reg reg - var v int32 - if p.Pcond != nil { - v = int32((p.Pcond.Pc - p.Pc) >> 1) - } - var opcode, opcode2 uint32 - switch p.As { - case ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE: - opcode = op_CGRJ - opcode2 = op_CGR - case ACMPUBEQ, ACMPUBGE, ACMPUBGT, ACMPUBLE, ACMPUBLT, ACMPUBNE: - opcode = op_CLGRJ - opcode2 = op_CLGR - } - mask := branchMask(ctxt, p) - if int32(int16(v)) != v { - zRRE(opcode2, uint32(p.From.Reg), uint32(p.Reg), asm) - zRIL(_c, op_BRCL, mask, uint32(v-sizeRRE/2), asm) - } else { - zRIE(_b, opcode, uint32(p.From.Reg), uint32(p.Reg), uint32(v), 0, 0, mask, 0, asm) - } - - case 90: // compare and branch reg $constant - var v int32 - if p.Pcond != nil { - v = int32((p.Pcond.Pc - p.Pc) >> 1) - } - var opcode, opcode2 uint32 - switch p.As { - case ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE: - opcode = op_CGIJ - opcode2 = op_CGFI - case ACMPUBEQ, ACMPUBGE, ACMPUBGT, ACMPUBLE, ACMPUBLT, ACMPUBNE: - opcode = op_CLGIJ - opcode2 = op_CLGFI - } - mask := branchMask(ctxt, p) - if int32(int16(v)) != v { - zRIL(_a, opcode2, uint32(p.From.Reg), uint32(regoff(ctxt, p.From3)), asm) - zRIL(_c, op_BRCL, mask, uint32(v-sizeRIL/2), asm) - } else { - zRIE(_c, opcode, uint32(p.From.Reg), mask, uint32(v), 0, 0, 0, uint32(regoff(ctxt, p.From3)), asm) - } - - case 93: // GOT lookup - v := vregoff(ctxt, &p.To) - if v != 0 { - ctxt.Diag("invalid offset against GOT slot %v", p) - } - zRIL(_b, op_LGRL, uint32(p.To.Reg), 0, asm) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + 2) - rel.Siz = 4 - rel.Sym = p.From.Sym - rel.Type = obj.R_GOTPCREL - rel.Add = 2 + int64(rel.Siz) - - case 94: // TLS local exec model - zRIL(_b, op_LARL, REGTMP, (sizeRIL+sizeRXY+sizeRI)>>1, asm) - zRXY(op_LG, uint32(p.To.Reg), REGTMP, 0, 0, asm) - zRI(op_BRC, 0xF, (sizeRI+8)>>1, asm) - *asm = append(*asm, 0, 0, 0, 0, 0, 0, 0, 0) - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc + sizeRIL + sizeRXY + sizeRI) - rel.Siz = 8 - rel.Sym = p.From.Sym - rel.Type = obj.R_TLS_LE - rel.Add = 0 - - case 95: // TLS initial exec model - // Assembly | Relocation symbol | Done Here? - // -------------------------------------------------------------- - // ear %r11, %a0 | | - // sllg %r11, %r11, 32 | | - // ear %r11, %a1 | | - // larl %r10, @indntpoff | R_390_TLS_IEENT | Y - // lg %r10, 0(%r10) | R_390_TLS_LOAD (tag) | Y - // la %r10, 0(%r10, %r11) | | - // -------------------------------------------------------------- - - // R_390_TLS_IEENT - zRIL(_b, op_LARL, REGTMP, 0, asm) - ieent := obj.Addrel(ctxt.Cursym) - ieent.Off = int32(ctxt.Pc + 2) - ieent.Siz = 4 - ieent.Sym = p.From.Sym - ieent.Type = obj.R_TLS_IE - ieent.Add = 2 + int64(ieent.Siz) - - // R_390_TLS_LOAD - zRXY(op_LGF, uint32(p.To.Reg), REGTMP, 0, 0, asm) - // TODO(mundaym): add R_390_TLS_LOAD relocation here - // not strictly required but might allow the linker to optimize - - case 96: // clear macro - length := vregoff(ctxt, &p.From) - offset := vregoff(ctxt, &p.To) - reg := p.To.Reg - if reg == 0 { - reg = o.param - } - if length <= 0 { - ctxt.Diag("cannot CLEAR %d bytes, must be greater than 0", length) - } - for length > 0 { - if offset < 0 || offset >= DISP12 { - if offset >= -DISP20/2 && offset < DISP20/2 { - zRXY(op_LAY, REGTMP, uint32(reg), 0, uint32(offset), asm) - } else { - if reg != REGTMP { - zRRE(op_LGR, REGTMP, uint32(reg), asm) - } - zRIL(_a, op_AGFI, REGTMP, uint32(offset), asm) - } - reg = REGTMP - offset = 0 - } - size := length - if size > 256 { - size = 256 - } - - switch size { - case 1: - zSI(op_MVI, 0, uint32(reg), uint32(offset), asm) - case 2: - zSIL(op_MVHHI, uint32(reg), uint32(offset), 0, asm) - case 4: - zSIL(op_MVHI, uint32(reg), uint32(offset), 0, asm) - case 8: - zSIL(op_MVGHI, uint32(reg), uint32(offset), 0, asm) - default: - zSS(_a, op_XC, uint32(size-1), 0, uint32(reg), uint32(offset), uint32(reg), uint32(offset), asm) - } - - length -= size - offset += size - } - - case 97: // store multiple - rstart := p.From.Reg - rend := p.Reg - offset := regoff(ctxt, &p.To) - reg := p.To.Reg - if reg == 0 { - reg = o.param - } - if offset < -DISP20/2 || offset >= DISP20/2 { - if reg != REGTMP { - zRRE(op_LGR, REGTMP, uint32(reg), asm) - } - zRIL(_a, op_AGFI, REGTMP, uint32(offset), asm) - reg = REGTMP - offset = 0 - } - switch p.As { - case ASTMY: - if offset >= 0 && offset < DISP12 { - zRS(op_STM, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm) - } else { - zRSY(op_STMY, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm) - } - case ASTMG: - zRSY(op_STMG, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm) - } - - case 98: // load multiple - rstart := p.Reg - rend := p.To.Reg - offset := regoff(ctxt, &p.From) - reg := p.From.Reg - if reg == 0 { - reg = o.param - } - if offset < -DISP20/2 || offset >= DISP20/2 { - if reg != REGTMP { - zRRE(op_LGR, REGTMP, uint32(reg), asm) - } - zRIL(_a, op_AGFI, REGTMP, uint32(offset), asm) - reg = REGTMP - offset = 0 - } - switch p.As { - case ALMY: - if offset >= 0 && offset < DISP12 { - zRS(op_LM, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm) - } else { - zRSY(op_LMY, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm) - } - case ALMG: - zRSY(op_LMG, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm) - } - - case 99: // interlocked load and op - if p.To.Index != 0 { - ctxt.Diag("cannot use indexed address") - } - offset := regoff(ctxt, &p.To) - if offset < -DISP20/2 || offset >= DISP20/2 { - ctxt.Diag("%v does not fit into 20-bit signed integer", offset) - } - var opcode uint32 - switch p.As { - case ALAA: - opcode = op_LAA - case ALAAG: - opcode = op_LAAG - case ALAAL: - opcode = op_LAAL - case ALAALG: - opcode = op_LAALG - case ALAN: - opcode = op_LAN - case ALANG: - opcode = op_LANG - case ALAX: - opcode = op_LAX - case ALAXG: - opcode = op_LAXG - case ALAO: - opcode = op_LAO - case ALAOG: - opcode = op_LAOG - } - zRSY(opcode, uint32(p.Reg), uint32(p.From.Reg), uint32(p.To.Reg), uint32(offset), asm) - - case 100: // VRX STORE - op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(vregoff(ctxt, p.From3)) - } - b2 := p.To.Reg - if b2 == 0 { - b2 = o.param - } - d2 := uint32(vregoff(ctxt, &p.To)) - zVRX(op, uint32(p.From.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm) - - case 101: // VRX LOAD - op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(vregoff(ctxt, p.From3)) - } - b2 := p.From.Reg - if b2 == 0 { - b2 = o.param - } - d2 := uint32(vregoff(ctxt, &p.From)) - zVRX(op, uint32(p.To.Reg), uint32(p.From.Index), uint32(b2), d2, m3, asm) - - case 102: // VRV SCATTER - op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(vregoff(ctxt, p.From3)) - } - b2 := p.To.Reg - if b2 == 0 { - b2 = o.param - } - d2 := uint32(vregoff(ctxt, &p.To)) - zVRV(op, uint32(p.From.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm) - - case 103: // VRV GATHER - op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(vregoff(ctxt, p.From3)) - } - b2 := p.From.Reg - if b2 == 0 { - b2 = o.param - } - d2 := uint32(vregoff(ctxt, &p.From)) - zVRV(op, uint32(p.To.Reg), uint32(p.From.Index), uint32(b2), d2, m3, asm) - - case 104: // VRS SHIFT/ROTATE and LOAD GR FROM VR ELEMENT - op, m4, _ := vop(p.As) - fr := p.Reg - if fr == 0 { - fr = p.To.Reg - } - bits := uint32(vregoff(ctxt, &p.From)) - zVRS(op, uint32(p.To.Reg), uint32(fr), uint32(p.From.Reg), bits, m4, asm) - - case 105: // VRS STORE MULTIPLE - op, _, _ := vop(p.As) - offset := uint32(vregoff(ctxt, &p.To)) - reg := p.To.Reg - if reg == 0 { - reg = o.param - } - zVRS(op, uint32(p.From.Reg), uint32(p.Reg), uint32(reg), offset, 0, asm) - - case 106: // VRS LOAD MULTIPLE - op, _, _ := vop(p.As) - offset := uint32(vregoff(ctxt, &p.From)) - reg := p.From.Reg - if reg == 0 { - reg = o.param - } - zVRS(op, uint32(p.Reg), uint32(p.To.Reg), uint32(reg), offset, 0, asm) - - case 107: // VRS STORE WITH LENGTH - op, _, _ := vop(p.As) - offset := uint32(vregoff(ctxt, &p.To)) - reg := p.To.Reg - if reg == 0 { - reg = o.param - } - zVRS(op, uint32(p.From.Reg), uint32(p.From3.Reg), uint32(reg), offset, 0, asm) - - case 108: // VRS LOAD WITH LENGTH - op, _, _ := vop(p.As) - offset := uint32(vregoff(ctxt, &p.From)) - reg := p.From.Reg - if reg == 0 { - reg = o.param - } - zVRS(op, uint32(p.To.Reg), uint32(p.From3.Reg), uint32(reg), offset, 0, asm) - - case 109: // VRI-a - op, _, _ := vop(p.As) - i2 := uint32(vregoff(ctxt, &p.From)) - switch p.As { - case AVZERO: - i2 = 0 - case AVONE: - i2 = 0xffff - } - m3 := uint32(0) - if p.From3 != nil { - m3 = uint32(vregoff(ctxt, p.From3)) - } - zVRIa(op, uint32(p.To.Reg), i2, m3, asm) - - case 110: - op, m4, _ := vop(p.As) - i2 := uint32(vregoff(ctxt, p.From3)) - i3 := uint32(vregoff(ctxt, &p.From)) - zVRIb(op, uint32(p.To.Reg), i2, i3, m4, asm) - - case 111: - op, m4, _ := vop(p.As) - i2 := uint32(vregoff(ctxt, &p.From)) - zVRIc(op, uint32(p.To.Reg), uint32(p.Reg), i2, m4, asm) - - case 112: - op, m5, _ := vop(p.As) - i4 := uint32(vregoff(ctxt, p.From3)) - zVRId(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), i4, m5, asm) - - case 113: - op, m4, _ := vop(p.As) - m5 := singleElementMask(p.As) - i3 := uint32(vregoff(ctxt, &p.From)) - zVRIe(op, uint32(p.To.Reg), uint32(p.Reg), i3, m5, m4, asm) - - case 114: // VRR-a - op, m3, m5 := vop(p.As) - m4 := singleElementMask(p.As) - zVRRa(op, uint32(p.To.Reg), uint32(p.From.Reg), m5, m4, m3, asm) - - case 115: // VRR-a COMPARE - op, m3, m5 := vop(p.As) - m4 := singleElementMask(p.As) - zVRRa(op, uint32(p.From.Reg), uint32(p.To.Reg), m5, m4, m3, asm) - - case 116: // VRR-a - - case 117: // VRR-b - op, m4, m5 := vop(p.As) - zVRRb(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), m5, m4, asm) - - case 118: // VRR-c - op, m4, m6 := vop(p.As) - m5 := singleElementMask(p.As) - v3 := p.Reg - if v3 == 0 { - v3 = p.To.Reg - } - zVRRc(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(v3), m6, m5, m4, asm) - - case 119: // VRR-c SHIFT/ROTATE/DIVIDE/SUB (rhs value on the left, like SLD, DIV etc.) - op, m4, m6 := vop(p.As) - m5 := singleElementMask(p.As) - v2 := p.Reg - if v2 == 0 { - v2 = p.To.Reg - } - zVRRc(op, uint32(p.To.Reg), uint32(v2), uint32(p.From.Reg), m6, m5, m4, asm) - - case 120: // VRR-d - op, m6, _ := vop(p.As) - m5 := singleElementMask(p.As) - v1 := uint32(p.To.Reg) - v2 := uint32(p.From3.Reg) - v3 := uint32(p.From.Reg) - v4 := uint32(p.Reg) - zVRRd(op, v1, v2, v3, m6, m5, v4, asm) - - case 121: // VRR-e - op, m6, _ := vop(p.As) - m5 := singleElementMask(p.As) - v1 := uint32(p.To.Reg) - v2 := uint32(p.From3.Reg) - v3 := uint32(p.From.Reg) - v4 := uint32(p.Reg) - zVRRe(op, v1, v2, v3, m6, m5, v4, asm) - - case 122: // VRR-f LOAD VRS FROM GRS DISJOINT - op, _, _ := vop(p.As) - zVRRf(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), asm) - - case 123: // VPDI $m4, V2, V3, V1 - op, _, _ := vop(p.As) - m4 := regoff(ctxt, p.From3) - zVRRc(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), 0, 0, uint32(m4), asm) - } -} - -func vregoff(ctxt *obj.Link, a *obj.Addr) int64 { - ctxt.Instoffset = 0 - if a != nil { - aclass(ctxt, a) - } - return ctxt.Instoffset -} - -func regoff(ctxt *obj.Link, a *obj.Addr) int32 { - return int32(vregoff(ctxt, a)) -} - -// zopload returns the RXY op for the given load -func zopload(ctxt *obj.Link, a obj.As) uint32 { - switch a { - // fixed point load - case AMOVD: - return op_LG - case AMOVW: - return op_LGF - case AMOVWZ: - return op_LLGF - case AMOVH: - return op_LGH - case AMOVHZ: - return op_LLGH - case AMOVB: - return op_LGB - case AMOVBZ: - return op_LLGC - - // floating point load - case AFMOVD: - return op_LDY - case AFMOVS: - return op_LEY - - // byte reversed load - case AMOVDBR: - return op_LRVG - case AMOVWBR: - return op_LRV - case AMOVHBR: - return op_LRVH - } - - ctxt.Diag("unknown store opcode %v", a) - return 0 -} - -// zopstore returns the RXY op for the given store -func zopstore(ctxt *obj.Link, a obj.As) uint32 { - switch a { - // fixed point store - case AMOVD: - return op_STG - case AMOVW, AMOVWZ: - return op_STY - case AMOVH, AMOVHZ: - return op_STHY - case AMOVB, AMOVBZ: - return op_STCY - - // floating point store - case AFMOVD: - return op_STDY - case AFMOVS: - return op_STEY - - // byte reversed store - case AMOVDBR: - return op_STRVG - case AMOVWBR: - return op_STRV - case AMOVHBR: - return op_STRVH - } - - ctxt.Diag("unknown store opcode %v", a) - return 0 -} - -// zoprre returns the RRE op for the given a -func zoprre(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ACMP: - return op_CGR - case ACMPU: - return op_CLGR - case AFCMPO: //ordered - return op_KDBR - case AFCMPU: //unordered - return op_CDBR - case ACEBR: - return op_CEBR - } - ctxt.Diag("unknown rre opcode %v", a) - return 0 -} - -// zoprr returns the RR op for the given a -func zoprr(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ACMPW: - return op_CR - case ACMPWU: - return op_CLR - } - ctxt.Diag("unknown rr opcode %v", a) - return 0 -} - -// zopril returns the RIL op for the given a -func zopril(ctxt *obj.Link, a obj.As) uint32 { - switch a { - case ACMP: - return op_CGFI - case ACMPU: - return op_CLGFI - case ACMPW: - return op_CFI - case ACMPWU: - return op_CLFI - } - ctxt.Diag("unknown ril opcode %v", a) - return 0 -} - -// z instructions sizes -const ( - sizeE = 2 - sizeI = 2 - sizeIE = 4 - sizeMII = 6 - sizeRI = 4 - sizeRI1 = 4 - sizeRI2 = 4 - sizeRI3 = 4 - sizeRIE = 6 - sizeRIE1 = 6 - sizeRIE2 = 6 - sizeRIE3 = 6 - sizeRIE4 = 6 - sizeRIE5 = 6 - sizeRIE6 = 6 - sizeRIL = 6 - sizeRIL1 = 6 - sizeRIL2 = 6 - sizeRIL3 = 6 - sizeRIS = 6 - sizeRR = 2 - sizeRRD = 4 - sizeRRE = 4 - sizeRRF = 4 - sizeRRF1 = 4 - sizeRRF2 = 4 - sizeRRF3 = 4 - sizeRRF4 = 4 - sizeRRF5 = 4 - sizeRRR = 2 - sizeRRS = 6 - sizeRS = 4 - sizeRS1 = 4 - sizeRS2 = 4 - sizeRSI = 4 - sizeRSL = 6 - sizeRSY = 6 - sizeRSY1 = 6 - sizeRSY2 = 6 - sizeRX = 4 - sizeRX1 = 4 - sizeRX2 = 4 - sizeRXE = 6 - sizeRXF = 6 - sizeRXY = 6 - sizeRXY1 = 6 - sizeRXY2 = 6 - sizeS = 4 - sizeSI = 4 - sizeSIL = 6 - sizeSIY = 6 - sizeSMI = 6 - sizeSS = 6 - sizeSS1 = 6 - sizeSS2 = 6 - sizeSS3 = 6 - sizeSS4 = 6 - sizeSS5 = 6 - sizeSS6 = 6 - sizeSSE = 6 - sizeSSF = 6 -) - -// instruction format variations -type form int - -const ( - _a form = iota - _b - _c - _d - _e - _f -) - -func zE(op uint32, asm *[]byte) { - *asm = append(*asm, uint8(op>>8), uint8(op)) -} - -func zI(op, i1 uint32, asm *[]byte) { - *asm = append(*asm, uint8(op>>8), uint8(i1)) -} - -func zMII(op, m1, ri2, ri3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(m1)<<4)|uint8((ri2>>8)&0x0F), - uint8(ri2), - uint8(ri3>>16), - uint8(ri3>>8), - uint8(ri3)) -} - -func zRI(op, r1_m1, i2_ri2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1_m1)<<4)|(uint8(op)&0x0F), - uint8(i2_ri2>>8), - uint8(i2_ri2)) -} - -// Expected argument values for the instruction formats. -// -// Format a1 a2 a3 a4 a5 a6 a7 -// ------------------------------------ -// a r1, 0, i2, 0, 0, m3, 0 -// b r1, r2, ri4, 0, 0, m3, 0 -// c r1, m3, ri4, 0, 0, 0, i2 -// d r1, r3, i2, 0, 0, 0, 0 -// e r1, r3, ri2, 0, 0, 0, 0 -// f r1, r2, 0, i3, i4, 0, i5 -// g r1, m3, i2, 0, 0, 0, 0 -func zRIE(f form, op, r1, r2_m3_r3, i2_ri4_ri2, i3, i4, m3, i2_i5 uint32, asm *[]byte) { - *asm = append(*asm, uint8(op>>8), uint8(r1)<<4|uint8(r2_m3_r3&0x0F)) - - switch f { - default: - *asm = append(*asm, uint8(i2_ri4_ri2>>8), uint8(i2_ri4_ri2)) - case _f: - *asm = append(*asm, uint8(i3), uint8(i4)) - } - - switch f { - case _a, _b: - *asm = append(*asm, uint8(m3)<<4) - default: - *asm = append(*asm, uint8(i2_i5)) - } - - *asm = append(*asm, uint8(op)) -} - -func zRIL(f form, op, r1_m1, i2_ri2 uint32, asm *[]byte) { - if f == _a || f == _b { - r1_m1 = r1_m1 - obj.RBaseS390X // this is a register base - } - *asm = append(*asm, - uint8(op>>8), - (uint8(r1_m1)<<4)|(uint8(op)&0x0F), - uint8(i2_ri2>>24), - uint8(i2_ri2>>16), - uint8(i2_ri2>>8), - uint8(i2_ri2)) -} - -func zRIS(op, r1, m3, b4, d4, i2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1)<<4)|uint8(m3&0x0F), - (uint8(b4)<<4)|(uint8(d4>>8)&0x0F), - uint8(d4), - uint8(i2), - uint8(op)) -} - -func zRR(op, r1, r2 uint32, asm *[]byte) { - *asm = append(*asm, uint8(op>>8), (uint8(r1)<<4)|uint8(r2&0x0F)) -} - -func zRRD(op, r1, r3, r2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(op), - uint8(r1)<<4, - (uint8(r3)<<4)|uint8(r2&0x0F)) -} - -func zRRE(op, r1, r2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(op), - 0, - (uint8(r1)<<4)|uint8(r2&0x0F)) -} - -func zRRF(op, r3_m3, m4, r1, r2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(op), - (uint8(r3_m3)<<4)|uint8(m4&0x0F), - (uint8(r1)<<4)|uint8(r2&0x0F)) -} - -func zRRS(op, r1, r2, b4, d4, m3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1)<<4)|uint8(r2&0x0F), - (uint8(b4)<<4)|uint8((d4>>8)&0x0F), - uint8(d4), - uint8(m3)<<4, - uint8(op)) -} - -func zRS(op, r1, r3_m3, b2, d2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1)<<4)|uint8(r3_m3&0x0F), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2)) -} - -func zRSI(op, r1, r3, ri2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1)<<4)|uint8(r3&0x0F), - uint8(ri2>>8), - uint8(ri2)) -} - -func zRSL(op, l1, b2, d2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(l1), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2), - uint8(op)) -} - -func zRSY(op, r1, r3_m3, b2, d2 uint32, asm *[]byte) { - dl2 := uint16(d2) & 0x0FFF - *asm = append(*asm, - uint8(op>>8), - (uint8(r1)<<4)|uint8(r3_m3&0x0F), - (uint8(b2)<<4)|(uint8(dl2>>8)&0x0F), - uint8(dl2), - uint8(d2>>12), - uint8(op)) -} - -func zRX(op, r1_m1, x2, b2, d2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1_m1)<<4)|uint8(x2&0x0F), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2)) -} - -func zRXE(op, r1, x2, b2, d2, m3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r1)<<4)|uint8(x2&0x0F), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2), - uint8(m3)<<4, - uint8(op)) -} - -func zRXF(op, r3, x2, b2, d2, m1 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r3)<<4)|uint8(x2&0x0F), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2), - uint8(m1)<<4, - uint8(op)) -} - -func zRXY(op, r1_m1, x2, b2, d2 uint32, asm *[]byte) { - dl2 := uint16(d2) & 0x0FFF - *asm = append(*asm, - uint8(op>>8), - (uint8(r1_m1)<<4)|uint8(x2&0x0F), - (uint8(b2)<<4)|(uint8(dl2>>8)&0x0F), - uint8(dl2), - uint8(d2>>12), - uint8(op)) -} - -func zS(op, b2, d2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(op), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2)) -} - -func zSI(op, i2, b1, d1 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(i2), - (uint8(b1)<<4)|uint8((d1>>8)&0x0F), - uint8(d1)) -} - -func zSIL(op, b1, d1, i2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(op), - (uint8(b1)<<4)|uint8((d1>>8)&0x0F), - uint8(d1), - uint8(i2>>8), - uint8(i2)) -} - -func zSIY(op, i2, b1, d1 uint32, asm *[]byte) { - dl1 := uint16(d1) & 0x0FFF - *asm = append(*asm, - uint8(op>>8), - uint8(i2), - (uint8(b1)<<4)|(uint8(dl1>>8)&0x0F), - uint8(dl1), - uint8(d1>>12), - uint8(op)) -} - -func zSMI(op, m1, b3, d3, ri2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(m1)<<4, - (uint8(b3)<<4)|uint8((d3>>8)&0x0F), - uint8(d3), - uint8(ri2>>8), - uint8(ri2)) -} - -// Expected argument values for the instruction formats. -// -// Format a1 a2 a3 a4 a5 a6 -// ------------------------------- -// a l1, 0, b1, d1, b2, d2 -// b l1, l2, b1, d1, b2, d2 -// c l1, i3, b1, d1, b2, d2 -// d r1, r3, b1, d1, b2, d2 -// e r1, r3, b2, d2, b4, d4 -// f 0, l2, b1, d1, b2, d2 -func zSS(f form, op, l1_r1, l2_i3_r3, b1_b2, d1_d2, b2_b4, d2_d4 uint32, asm *[]byte) { - *asm = append(*asm, uint8(op>>8)) - - switch f { - case _a: - *asm = append(*asm, uint8(l1_r1)) - case _b, _c, _d, _e: - *asm = append(*asm, (uint8(l1_r1)<<4)|uint8(l2_i3_r3&0x0F)) - case _f: - *asm = append(*asm, uint8(l2_i3_r3)) - } - - *asm = append(*asm, - (uint8(b1_b2)<<4)|uint8((d1_d2>>8)&0x0F), - uint8(d1_d2), - (uint8(b2_b4)<<4)|uint8((d2_d4>>8)&0x0F), - uint8(d2_d4)) -} - -func zSSE(op, b1, d1, b2, d2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(op), - (uint8(b1)<<4)|uint8((d1>>8)&0x0F), - uint8(d1), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2)) -} - -func zSSF(op, r3, b1, d1, b2, d2 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(r3)<<4)|(uint8(op)&0x0F), - (uint8(b1)<<4)|uint8((d1>>8)&0x0F), - uint8(d1), - (uint8(b2)<<4)|uint8((d2>>8)&0x0F), - uint8(d2)) -} - -func rxb(va, vb, vc, vd uint32) uint8 { - mask := uint8(0) - if va >= REG_V16 && va <= REG_V31 { - mask |= 0x8 - } - if vb >= REG_V16 && vb <= REG_V31 { - mask |= 0x4 - } - if vc >= REG_V16 && vc <= REG_V31 { - mask |= 0x2 - } - if vd >= REG_V16 && vd <= REG_V31 { - mask |= 0x1 - } - return mask -} - -func zVRX(op, v1, x2, b2, d2, m3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(x2)&0xf), - (uint8(b2)<<4)|(uint8(d2>>8)&0xf), - uint8(d2), - (uint8(m3)<<4)|rxb(v1, 0, 0, 0), - uint8(op)) -} - -func zVRV(op, v1, v2, b2, d2, m3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - (uint8(b2)<<4)|(uint8(d2>>8)&0xf), - uint8(d2), - (uint8(m3)<<4)|rxb(v1, v2, 0, 0), - uint8(op)) -} - -func zVRS(op, v1, v3_r3, b2, d2, m4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v3_r3)&0xf), - (uint8(b2)<<4)|(uint8(d2>>8)&0xf), - uint8(d2), - (uint8(m4)<<4)|rxb(v1, v3_r3, 0, 0), - uint8(op)) -} - -func zVRRa(op, v1, v2, m5, m4, m3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - 0, - (uint8(m5)<<4)|(uint8(m4)&0xf), - (uint8(m3)<<4)|rxb(v1, v2, 0, 0), - uint8(op)) -} - -func zVRRb(op, v1, v2, v3, m5, m4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - uint8(v3)<<4, - uint8(m5)<<4, - (uint8(m4)<<4)|rxb(v1, v2, v3, 0), - uint8(op)) -} - -func zVRRc(op, v1, v2, v3, m6, m5, m4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - uint8(v3)<<4, - (uint8(m6)<<4)|(uint8(m5)&0xf), - (uint8(m4)<<4)|rxb(v1, v2, v3, 0), - uint8(op)) -} - -func zVRRd(op, v1, v2, v3, m5, m6, v4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - (uint8(v3)<<4)|(uint8(m5)&0xf), - uint8(m6)<<4, - (uint8(v4)<<4)|rxb(v1, v2, v3, v4), - uint8(op)) -} - -func zVRRe(op, v1, v2, v3, m6, m5, v4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - (uint8(v3)<<4)|(uint8(m6)&0xf), - uint8(m5), - (uint8(v4)<<4)|rxb(v1, v2, v3, v4), - uint8(op)) -} - -func zVRRf(op, v1, r2, r3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(r2)&0xf), - uint8(r3)<<4, - 0, - rxb(v1, 0, 0, 0), - uint8(op)) -} - -func zVRIa(op, v1, i2, m3 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(v1)<<4, - uint8(i2>>8), - uint8(i2), - (uint8(m3)<<4)|rxb(v1, 0, 0, 0), - uint8(op)) -} - -func zVRIb(op, v1, i2, i3, m4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - uint8(v1)<<4, - uint8(i2), - uint8(i3), - (uint8(m4)<<4)|rxb(v1, 0, 0, 0), - uint8(op)) -} - -func zVRIc(op, v1, v3, i2, m4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v3)&0xf), - uint8(i2>>8), - uint8(i2), - (uint8(m4)<<4)|rxb(v1, v3, 0, 0), - uint8(op)) -} - -func zVRId(op, v1, v2, v3, i4, m5 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - uint8(v3)<<4, - uint8(i4), - (uint8(m5)<<4)|rxb(v1, v2, v3, 0), - uint8(op)) -} - -func zVRIe(op, v1, v2, i3, m5, m4 uint32, asm *[]byte) { - *asm = append(*asm, - uint8(op>>8), - (uint8(v1)<<4)|(uint8(v2)&0xf), - uint8(i3>>4), - (uint8(i3)<<4)|(uint8(m5)&0xf), - (uint8(m4)<<4)|rxb(v1, v2, 0, 0), - uint8(op)) -} diff --git a/vendor/github.com/google/gops/internal/obj/s390x/listz.go b/vendor/github.com/google/gops/internal/obj/s390x/listz.go deleted file mode 100644 index 468b8588..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/listz.go +++ /dev/null @@ -1,74 +0,0 @@ -// Based on cmd/internal/obj/ppc64/list9.go. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package s390x - -import ( - "fmt" - - "github.com/google/gops/internal/obj" -) - -func init() { - obj.RegisterRegister(obj.RBaseS390X, REG_R0+1024, Rconv) - obj.RegisterOpcode(obj.ABaseS390X, Anames) -} - -func Rconv(r int) string { - if r == 0 { - return "NONE" - } - if r == REGG { - // Special case. - return "g" - } - if REG_R0 <= r && r <= REG_R15 { - return fmt.Sprintf("R%d", r-REG_R0) - } - if REG_F0 <= r && r <= REG_F15 { - return fmt.Sprintf("F%d", r-REG_F0) - } - if REG_AR0 <= r && r <= REG_AR15 { - return fmt.Sprintf("AR%d", r-REG_AR0) - } - if REG_V0 <= r && r <= REG_V31 { - return fmt.Sprintf("V%d", r-REG_V0) - } - return fmt.Sprintf("Rgok(%d)", r-obj.RBaseS390X) -} - -func DRconv(a int) string { - s := "C_??" - if a >= C_NONE && a <= C_NCLASS { - s = cnamesz[a] - } - var fp string - fp += s - return fp -} diff --git a/vendor/github.com/google/gops/internal/obj/s390x/objz.go b/vendor/github.com/google/gops/internal/obj/s390x/objz.go deleted file mode 100644 index bbf4c35c..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/objz.go +++ /dev/null @@ -1,1029 +0,0 @@ -// Based on cmd/internal/obj/ppc64/obj9.go. -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package s390x - -import ( - "fmt" - "math" - - "github.com/google/gops/internal/obj" - "github.com/google/gops/internal/sys" -) - -func progedit(ctxt *obj.Link, p *obj.Prog) { - p.From.Class = 0 - p.To.Class = 0 - - // Rewrite BR/BL to symbol as TYPE_BRANCH. - switch p.As { - case ABR, - ABL, - obj.ARET, - obj.ADUFFZERO, - obj.ADUFFCOPY: - if p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - } - - // Rewrite float constants to values stored in memory unless they are +0. - switch p.As { - case AFMOVS: - if p.From.Type == obj.TYPE_FCONST { - f32 := float32(p.From.Val.(float64)) - i32 := math.Float32bits(f32) - if i32 == 0 { // +0 - break - } - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 4 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - case AFMOVD: - if p.From.Type == obj.TYPE_FCONST { - i64 := math.Float64bits(p.From.Val.(float64)) - if i64 == 0 { // +0 - break - } - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - - // put constants not loadable by LOAD IMMEDIATE into memory - case AMOVD: - if p.From.Type == obj.TYPE_CONST { - val := p.From.Offset - if int64(int32(val)) != val && - int64(uint32(val)) != val && - int64(uint64(val)&(0xffffffff<<32)) != val { - literal := fmt.Sprintf("$i64.%016x", uint64(p.From.Offset)) - s := obj.Linklookup(ctxt, literal, 0) - s.Size = 8 - p.From.Type = obj.TYPE_MEM - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Name = obj.NAME_EXTERN - p.From.Offset = 0 - } - } - } - - // Rewrite SUB constants into ADD. - switch p.As { - case ASUBC: - if p.From.Type == obj.TYPE_CONST && isint32(-p.From.Offset) { - p.From.Offset = -p.From.Offset - p.As = AADDC - } - - case ASUB: - if p.From.Type == obj.TYPE_CONST && isint32(-p.From.Offset) { - p.From.Offset = -p.From.Offset - p.As = AADD - } - } - - if ctxt.Flag_dynlink { - rewriteToUseGot(ctxt, p) - } -} - -// Rewrite p, if necessary, to access global data via the global offset table. -func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { - // At the moment EXRL instructions are not emitted by the compiler and only reference local symbols in - // assembly code. - if p.As == AEXRL { - return - } - - // We only care about global data: NAME_EXTERN means a global - // symbol in the Go sense, and p.Sym.Local is true for a few - // internally defined symbols. - if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - // MOVD $sym, Rx becomes MOVD sym@GOT, Rx - // MOVD $sym+, Rx becomes MOVD sym@GOT, Rx; ADD , Rx - if p.To.Type != obj.TYPE_REG || p.As != AMOVD { - ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p) - } - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - q := p - if p.From.Offset != 0 { - q = obj.Appendp(ctxt, p) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = p.From.Offset - q.To = p.To - p.From.Offset = 0 - } - } - if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - var source *obj.Addr - // MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry - // MOVD Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP) - // An addition may be inserted between the two MOVs if there is an offset. - if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) - } - source = &p.From - } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - source = &p.To - } else { - return - } - if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { - return - } - if source.Sym.Type == obj.STLSBSS { - return - } - if source.Type != obj.TYPE_MEM { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - p1 := obj.Appendp(ctxt, p) - p2 := obj.Appendp(ctxt, p1) - - p1.As = AMOVD - p1.From.Type = obj.TYPE_MEM - p1.From.Sym = source.Sym - p1.From.Name = obj.NAME_GOTREF - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REGTMP - - p2.As = p.As - p2.From = p.From - p2.To = p.To - if p.From.Name == obj.NAME_EXTERN { - p2.From.Reg = REGTMP - p2.From.Name = obj.NAME_NONE - p2.From.Sym = nil - } else if p.To.Name == obj.NAME_EXTERN { - p2.To.Reg = REGTMP - p2.To.Name = obj.NAME_NONE - p2.To.Sym = nil - } else { - return - } - obj.Nopout(p) -} - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - // TODO(minux): add morestack short-cuts with small fixed frame-size. - ctxt.Cursym = cursym - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - p := cursym.Text - textstksiz := p.To.Offset - if textstksiz == -8 { - // Compatibility hack. - p.From3.Offset |= obj.NOFRAME - textstksiz = 0 - } - if textstksiz%8 != 0 { - ctxt.Diag("frame size %d not a multiple of 8", textstksiz) - } - if p.From3.Offset&obj.NOFRAME != 0 { - if textstksiz != 0 { - ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz) - } - } - - cursym.Args = p.To.Val.(int32) - cursym.Locals = int32(textstksiz) - - /* - * find leaf subroutines - * strip NOPs - * expand RET - * expand BECOME pseudo - */ - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f noops\n", obj.Cputime()) - } - - var q *obj.Prog - var q1 *obj.Prog - for p := cursym.Text; p != nil; p = p.Link { - switch p.As { - /* too hard, just leave alone */ - case obj.ATEXT: - q = p - - p.Mark |= LABEL | LEAF | SYNC - if p.Link != nil { - p.Link.Mark |= LABEL - } - - case ASYNC, - AWORD: - q = p - p.Mark |= LABEL | SYNC - continue - - case AMOVW, AMOVWZ, AMOVD: - q = p - if p.From.Reg >= REG_RESERVED || p.To.Reg >= REG_RESERVED { - p.Mark |= LABEL | SYNC - } - continue - - case AFABS, - AFADD, - AFDIV, - AFMADD, - AFMOVD, - AFMOVS, - AFMSUB, - AFMUL, - AFNABS, - AFNEG, - AFNMADD, - AFNMSUB, - ALEDBR, - ALDEBR, - AFSUB: - q = p - - p.Mark |= FLOAT - continue - - case ABL, - ABCL, - obj.ADUFFZERO, - obj.ADUFFCOPY: - cursym.Text.Mark &^= LEAF - fallthrough - - case ABC, - ABEQ, - ABGE, - ABGT, - ABLE, - ABLT, - ABLEU, - ABLTU, - ABNE, - ABR, - ABVC, - ABVS, - ACMPBEQ, - ACMPBGE, - ACMPBGT, - ACMPBLE, - ACMPBLT, - ACMPBNE, - ACMPUBEQ, - ACMPUBGE, - ACMPUBGT, - ACMPUBLE, - ACMPUBLT, - ACMPUBNE: - p.Mark |= BRANCH - q = p - q1 = p.Pcond - if q1 != nil { - for q1.As == obj.ANOP { - q1 = q1.Link - p.Pcond = q1 - } - - if q1.Mark&LEAF == 0 { - q1.Mark |= LABEL - } - } else { - p.Mark |= LABEL - } - q1 = p.Link - if q1 != nil { - q1.Mark |= LABEL - } - continue - - case AFCMPO, AFCMPU: - q = p - p.Mark |= FCMP | FLOAT - continue - - case obj.ARET: - q = p - if p.Link != nil { - p.Link.Mark |= LABEL - } - continue - - case obj.ANOP: - q1 = p.Link - q.Link = q1 /* q is non-nop */ - q1.Mark |= p.Mark - continue - - default: - q = p - continue - } - } - - autosize := int32(0) - var p1 *obj.Prog - var p2 *obj.Prog - var pLast *obj.Prog - var pPre *obj.Prog - var pPreempt *obj.Prog - wasSplit := false - for p := cursym.Text; p != nil; p = p.Link { - pLast = p - switch p.As { - case obj.ATEXT: - autosize = int32(textstksiz) - - if p.Mark&LEAF != 0 && autosize == 0 { - // A leaf function with no locals has no frame. - p.From3.Offset |= obj.NOFRAME - } - - if p.From3.Offset&obj.NOFRAME == 0 { - // If there is a stack frame at all, it includes - // space to save the LR. - autosize += int32(ctxt.FixedFrameSize()) - } - - if p.Mark&LEAF != 0 && autosize < obj.StackSmall { - // A leaf function with a small stack can be marked - // NOSPLIT, avoiding a stack check. - p.From3.Offset |= obj.NOSPLIT - } - - p.To.Offset = int64(autosize) - - q = p - - if p.From3.Offset&obj.NOSPLIT == 0 { - p, pPreempt = stacksplitPre(ctxt, p, autosize) // emit pre part of split check - pPre = p - wasSplit = true //need post part of split - } - - if autosize != 0 { - // Make sure to save link register for non-empty frame, even if - // it is a leaf function, so that traceback works. - // Store link register before decrementing SP, so if a signal comes - // during the execution of the function prologue, the traceback - // code will not see a half-updated stack frame. - q = obj.Appendp(ctxt, p) - q.As = AMOVD - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_LR - q.To.Type = obj.TYPE_MEM - q.To.Reg = REGSP - q.To.Offset = int64(-autosize) - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_ADDR - q.From.Offset = int64(-autosize) - q.From.Reg = REGSP // not actually needed - REGSP is assumed if no reg is provided - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = autosize - } else if cursym.Text.Mark&LEAF == 0 { - // A very few functions that do not return to their caller - // (e.g. gogo) are not identified as leaves but still have - // no frame. - cursym.Text.Mark |= LEAF - } - - if cursym.Text.Mark&LEAF != 0 { - cursym.Set(obj.AttrLeaf, true) - break - } - - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOVD g_panic(g), R3 - // CMP R3, $0 - // BEQ end - // MOVD panic_argp(R3), R4 - // ADD $(autosize+8), R1, R5 - // CMP R4, R5 - // BNE end - // ADD $8, R1, R6 - // MOVD R6, panic_argp(R3) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not a s390x NOP: it encodes to 0 instruction bytes. - - q = obj.Appendp(ctxt, q) - - q.As = AMOVD - q.From.Type = obj.TYPE_MEM - q.From.Reg = REGG - q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R3 - - q = obj.Appendp(ctxt, q) - q.As = ACMP - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R3 - q.To.Type = obj.TYPE_CONST - q.To.Offset = 0 - - q = obj.Appendp(ctxt, q) - q.As = ABEQ - q.To.Type = obj.TYPE_BRANCH - p1 = q - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_MEM - q.From.Reg = REG_R3 - q.From.Offset = 0 // Panic.argp - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R4 - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(autosize) + ctxt.FixedFrameSize() - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R5 - - q = obj.Appendp(ctxt, q) - q.As = ACMP - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R4 - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R5 - - q = obj.Appendp(ctxt, q) - q.As = ABNE - q.To.Type = obj.TYPE_BRANCH - p2 = q - - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = ctxt.FixedFrameSize() - q.Reg = REGSP - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R6 - - q = obj.Appendp(ctxt, q) - q.As = AMOVD - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R6 - q.To.Type = obj.TYPE_MEM - q.To.Reg = REG_R3 - q.To.Offset = 0 // Panic.argp - - q = obj.Appendp(ctxt, q) - - q.As = obj.ANOP - p1.Pcond = q - p2.Pcond = q - } - - case obj.ARET: - if p.From.Type == obj.TYPE_CONST { - ctxt.Diag("using BECOME (%v) is not supported!", p) - break - } - - retTarget := p.To.Sym - - if cursym.Text.Mark&LEAF != 0 { - if autosize == 0 { - p.As = ABR - p.From = obj.Addr{} - if retTarget == nil { - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_LR - } else { - p.To.Type = obj.TYPE_BRANCH - p.To.Sym = retTarget - } - p.Mark |= BRANCH - break - } - - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autosize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REGSP - p.Spadj = -autosize - - q = obj.Appendp(ctxt, p) - q.As = ABR - q.From = obj.Addr{} - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_LR - q.Mark |= BRANCH - q.Spadj = autosize - break - } - - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGSP - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_LR - - q = p - - if autosize != 0 { - q = obj.Appendp(ctxt, q) - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(autosize) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = -autosize - } - - q = obj.Appendp(ctxt, q) - q.As = ABR - q.From = obj.Addr{} - if retTarget == nil { - q.To.Type = obj.TYPE_REG - q.To.Reg = REG_LR - } else { - q.To.Type = obj.TYPE_BRANCH - q.To.Sym = retTarget - } - q.Mark |= BRANCH - q.Spadj = autosize - - case AADD: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST { - p.Spadj = int32(-p.From.Offset) - } - } - } - if wasSplit { - pLast = stacksplitPost(ctxt, pLast, pPre, pPreempt, autosize) // emit post part of split check - } -} - -/* -// instruction scheduling - if(debug['Q'] == 0) - return; - - curtext = nil; - q = nil; // p - 1 - q1 = firstp; // top of block - o = 0; // count of instructions - for(p = firstp; p != nil; p = p1) { - p1 = p->link; - o++; - if(p->mark & NOSCHED){ - if(q1 != p){ - sched(q1, q); - } - for(; p != nil; p = p->link){ - if(!(p->mark & NOSCHED)) - break; - q = p; - } - p1 = p; - q1 = p; - o = 0; - continue; - } - if(p->mark & (LABEL|SYNC)) { - if(q1 != p) - sched(q1, q); - q1 = p; - o = 1; - } - if(p->mark & (BRANCH|SYNC)) { - sched(q1, p); - q1 = p1; - o = 0; - } - if(o >= NSCHED) { - sched(q1, p); - q1 = p1; - o = 0; - } - q = p; - } -*/ -func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *obj.Prog) { - var q *obj.Prog - - // MOVD g_stackguard(g), R3 - p = obj.Appendp(ctxt, p) - - p.As = AMOVD - p.From.Type = obj.TYPE_MEM - p.From.Reg = REGG - p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - - q = nil - if framesize <= obj.StackSmall { - // small stack: SP < stackguard - // CMP stackguard, SP - - //p.To.Type = obj.TYPE_REG - //p.To.Reg = REGSP - - // q1: BLT done - - p = obj.Appendp(ctxt, p) - //q1 = p - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.Reg = REGSP - p.As = ACMPUBGE - p.To.Type = obj.TYPE_BRANCH - //p = obj.Appendp(ctxt, p) - - //p.As = ACMPU - //p.From.Type = obj.TYPE_REG - //p.From.Reg = REG_R3 - //p.To.Type = obj.TYPE_REG - //p.To.Reg = REGSP - - //p = obj.Appendp(ctxt, p) - //p.As = ABGE - //p.To.Type = obj.TYPE_BRANCH - - } else if framesize <= obj.StackBig { - // large stack: SP-framesize < stackguard-StackSmall - // ADD $-framesize, SP, R4 - // CMP stackguard, R4 - p = obj.Appendp(ctxt, p) - - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(-framesize) - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.Reg = REG_R4 - p.As = ACMPUBGE - p.To.Type = obj.TYPE_BRANCH - - } else { - // Such a large stack we need to protect against wraparound. - // If SP is close to zero: - // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // - // Preemption sets stackguard to StackPreempt, a very large value. - // That breaks the math above, so we have to check for that explicitly. - // // stackguard is R3 - // CMP R3, $StackPreempt - // BEQ label-of-call-to-morestack - // ADD $StackGuard, SP, R4 - // SUB R3, R4 - // MOVD $(framesize+(StackGuard-StackSmall)), TEMP - // CMPUBGE TEMP, R4 - p = obj.Appendp(ctxt, p) - - p.As = ACMP - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.To.Type = obj.TYPE_CONST - p.To.Offset = obj.StackPreempt - - p = obj.Appendp(ctxt, p) - q = p - p.As = ABEQ - p.To.Type = obj.TYPE_BRANCH - - p = obj.Appendp(ctxt, p) - p.As = AADD - p.From.Type = obj.TYPE_CONST - p.From.Offset = obj.StackGuard - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.As = ASUB - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 - - p = obj.Appendp(ctxt, p) - p.As = AMOVD - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall - p.To.Type = obj.TYPE_REG - p.To.Reg = REGTMP - - p = obj.Appendp(ctxt, p) - p.From.Type = obj.TYPE_REG - p.From.Reg = REGTMP - p.Reg = REG_R4 - p.As = ACMPUBGE - p.To.Type = obj.TYPE_BRANCH - } - - return p, q -} - -func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, framesize int32) *obj.Prog { - // Now we are at the end of the function, but logically - // we are still in function prologue. We need to fix the - // SP data and PCDATA. - spfix := obj.Appendp(ctxt, p) - spfix.As = obj.ANOP - spfix.Spadj = -framesize - - pcdata := obj.Appendp(ctxt, spfix) - pcdata.Lineno = ctxt.Cursym.Text.Lineno - pcdata.Mode = ctxt.Cursym.Text.Mode - pcdata.As = obj.APCDATA - pcdata.From.Type = obj.TYPE_CONST - pcdata.From.Offset = obj.PCDATA_StackMapIndex - pcdata.To.Type = obj.TYPE_CONST - pcdata.To.Offset = -1 // pcdata starts at -1 at function entry - - // MOVD LR, R5 - p = obj.Appendp(ctxt, pcdata) - pPre.Pcond = p - p.As = AMOVD - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_LR - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R5 - if pPreempt != nil { - pPreempt.Pcond = p - } - - // BL runtime.morestack(SB) - p = obj.Appendp(ctxt, p) - - p.As = ABL - p.To.Type = obj.TYPE_BRANCH - if ctxt.Cursym.CFunc() { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) - } else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0) - } else { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack", 0) - } - - // BR start - p = obj.Appendp(ctxt, p) - - p.As = ABR - p.To.Type = obj.TYPE_BRANCH - p.Pcond = ctxt.Cursym.Text.Link - return p -} - -var pc_cnt int64 - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - pc_cnt = 0 - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func relinv(a obj.As) obj.As { - switch a { - case ABEQ: - return ABNE - case ABNE: - return ABEQ - - case ABGE: - return ABLT - case ABLT: - return ABGE - - case ABGT: - return ABLE - case ABLE: - return ABGT - - case ABVC: - return ABVS - case ABVS: - return ABVC - } - - return 0 -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var r *obj.Prog - var b obj.As - - for p != nil { - a := p.As - if a == ABR { - q = p.Pcond - if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) { - p.Mark |= FOLL - (*last).Link = p - *last = p - (*last).Pc = pc_cnt - pc_cnt += 1 - p = p.Link - xfol(ctxt, p, last) - p = q - if p != nil && p.Mark&FOLL == 0 { - continue - } - return - } - - if q != nil { - p.Mark |= FOLL - p = q - if p.Mark&FOLL == 0 { - continue - } - } - } - - if p.Mark&FOLL != 0 { - q = p - for i := 0; i < 4; i, q = i+1, q.Link { - if q == *last || (q.Mark&NOSCHED != 0) { - break - } - b = 0 /* set */ - a = q.As - if a == obj.ANOP { - i-- - continue - } - if a != ABR && a != obj.ARET { - if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { - continue - } - b = relinv(a) - if b == 0 { - continue - } - } - - for { - r = ctxt.NewProg() - *r = *p - if r.Mark&FOLL == 0 { - fmt.Printf("can't happen 1\n") - } - r.Mark |= FOLL - if p != q { - p = p.Link - (*last).Link = r - *last = r - (*last).Pc = pc_cnt - pc_cnt += 1 - continue - } - - (*last).Link = r - *last = r - (*last).Pc = pc_cnt - pc_cnt += 1 - if a == ABR || a == obj.ARET { - return - } - r.As = b - r.Pcond = p.Link - r.Link = p.Pcond - if r.Link.Mark&FOLL == 0 { - xfol(ctxt, r.Link, last) - } - if r.Pcond.Mark&FOLL == 0 { - fmt.Printf("can't happen 2\n") - } - return - } - } - - a = ABR - q = ctxt.NewProg() - q.As = a - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - p.Mark |= FOLL - (*last).Link = p - *last = p - (*last).Pc = pc_cnt - pc_cnt += 1 - - if a == ABR || a == obj.ARET { - if p.Mark&NOSCHED != 0 { - p = p.Link - continue - } - - return - } - - if p.Pcond != nil { - if a != ABL && p.Link != nil { - xfol(ctxt, p.Link, last) - p = p.Pcond - if p == nil || (p.Mark&FOLL != 0) { - return - } - continue - } - } - - p = p.Link - } -} - -var unaryDst = map[obj.As]bool{ - ASTCK: true, - ASTCKC: true, - ASTCKE: true, - ASTCKF: true, - ANEG: true, - ANEGW: true, - AVONE: true, - AVZERO: true, -} - -var Links390x = obj.LinkArch{ - Arch: sys.ArchS390X, - Preprocess: preprocess, - Assemble: spanz, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, -} diff --git a/vendor/github.com/google/gops/internal/obj/s390x/vector.go b/vendor/github.com/google/gops/internal/obj/s390x/vector.go deleted file mode 100644 index 7aa62229..00000000 --- a/vendor/github.com/google/gops/internal/obj/s390x/vector.go +++ /dev/null @@ -1,1061 +0,0 @@ -// Copyright 2016 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 ( - "github.com/google/gops/internal/obj" -) - -// This file contains utility functions for use when -// assembling vector instructions. - -// vop returns the opcode, element size and condition -// setting for the given (possibly extended) mnemonic. -func vop(as obj.As) (opcode, es, cs uint32) { - switch as { - default: - return 0, 0, 0 - case AVA: - return op_VA, 0, 0 - case AVAB: - return op_VA, 0, 0 - case AVAH: - return op_VA, 1, 0 - case AVAF: - return op_VA, 2, 0 - case AVAG: - return op_VA, 3, 0 - case AVAQ: - return op_VA, 4, 0 - case AVACC: - return op_VACC, 0, 0 - case AVACCB: - return op_VACC, 0, 0 - case AVACCH: - return op_VACC, 1, 0 - case AVACCF: - return op_VACC, 2, 0 - case AVACCG: - return op_VACC, 3, 0 - case AVACCQ: - return op_VACC, 4, 0 - case AVAC: - return op_VAC, 0, 0 - case AVACQ: - return op_VAC, 4, 0 - case AVACCC: - return op_VACCC, 0, 0 - case AVACCCQ: - return op_VACCC, 4, 0 - case AVN: - return op_VN, 0, 0 - case AVNC: - return op_VNC, 0, 0 - case AVAVG: - return op_VAVG, 0, 0 - case AVAVGB: - return op_VAVG, 0, 0 - case AVAVGH: - return op_VAVG, 1, 0 - case AVAVGF: - return op_VAVG, 2, 0 - case AVAVGG: - return op_VAVG, 3, 0 - case AVAVGL: - return op_VAVGL, 0, 0 - case AVAVGLB: - return op_VAVGL, 0, 0 - case AVAVGLH: - return op_VAVGL, 1, 0 - case AVAVGLF: - return op_VAVGL, 2, 0 - case AVAVGLG: - return op_VAVGL, 3, 0 - case AVCKSM: - return op_VCKSM, 0, 0 - case AVCEQ: - return op_VCEQ, 0, 0 - case AVCEQB: - return op_VCEQ, 0, 0 - case AVCEQH: - return op_VCEQ, 1, 0 - case AVCEQF: - return op_VCEQ, 2, 0 - case AVCEQG: - return op_VCEQ, 3, 0 - case AVCEQBS: - return op_VCEQ, 0, 1 - case AVCEQHS: - return op_VCEQ, 1, 1 - case AVCEQFS: - return op_VCEQ, 2, 1 - case AVCEQGS: - return op_VCEQ, 3, 1 - case AVCH: - return op_VCH, 0, 0 - case AVCHB: - return op_VCH, 0, 0 - case AVCHH: - return op_VCH, 1, 0 - case AVCHF: - return op_VCH, 2, 0 - case AVCHG: - return op_VCH, 3, 0 - case AVCHBS: - return op_VCH, 0, 1 - case AVCHHS: - return op_VCH, 1, 1 - case AVCHFS: - return op_VCH, 2, 1 - case AVCHGS: - return op_VCH, 3, 1 - case AVCHL: - return op_VCHL, 0, 0 - case AVCHLB: - return op_VCHL, 0, 0 - case AVCHLH: - return op_VCHL, 1, 0 - case AVCHLF: - return op_VCHL, 2, 0 - case AVCHLG: - return op_VCHL, 3, 0 - case AVCHLBS: - return op_VCHL, 0, 1 - case AVCHLHS: - return op_VCHL, 1, 1 - case AVCHLFS: - return op_VCHL, 2, 1 - case AVCHLGS: - return op_VCHL, 3, 1 - case AVCLZ: - return op_VCLZ, 0, 0 - case AVCLZB: - return op_VCLZ, 0, 0 - case AVCLZH: - return op_VCLZ, 1, 0 - case AVCLZF: - return op_VCLZ, 2, 0 - case AVCLZG: - return op_VCLZ, 3, 0 - case AVCTZ: - return op_VCTZ, 0, 0 - case AVCTZB: - return op_VCTZ, 0, 0 - case AVCTZH: - return op_VCTZ, 1, 0 - case AVCTZF: - return op_VCTZ, 2, 0 - case AVCTZG: - return op_VCTZ, 3, 0 - case AVEC: - return op_VEC, 0, 0 - case AVECB: - return op_VEC, 0, 0 - case AVECH: - return op_VEC, 1, 0 - case AVECF: - return op_VEC, 2, 0 - case AVECG: - return op_VEC, 3, 0 - case AVECL: - return op_VECL, 0, 0 - case AVECLB: - return op_VECL, 0, 0 - case AVECLH: - return op_VECL, 1, 0 - case AVECLF: - return op_VECL, 2, 0 - case AVECLG: - return op_VECL, 3, 0 - case AVERIM: - return op_VERIM, 0, 0 - case AVERIMB: - return op_VERIM, 0, 0 - case AVERIMH: - return op_VERIM, 1, 0 - case AVERIMF: - return op_VERIM, 2, 0 - case AVERIMG: - return op_VERIM, 3, 0 - case AVERLL: - return op_VERLL, 0, 0 - case AVERLLB: - return op_VERLL, 0, 0 - case AVERLLH: - return op_VERLL, 1, 0 - case AVERLLF: - return op_VERLL, 2, 0 - case AVERLLG: - return op_VERLL, 3, 0 - case AVERLLV: - return op_VERLLV, 0, 0 - case AVERLLVB: - return op_VERLLV, 0, 0 - case AVERLLVH: - return op_VERLLV, 1, 0 - case AVERLLVF: - return op_VERLLV, 2, 0 - case AVERLLVG: - return op_VERLLV, 3, 0 - case AVESLV: - return op_VESLV, 0, 0 - case AVESLVB: - return op_VESLV, 0, 0 - case AVESLVH: - return op_VESLV, 1, 0 - case AVESLVF: - return op_VESLV, 2, 0 - case AVESLVG: - return op_VESLV, 3, 0 - case AVESL: - return op_VESL, 0, 0 - case AVESLB: - return op_VESL, 0, 0 - case AVESLH: - return op_VESL, 1, 0 - case AVESLF: - return op_VESL, 2, 0 - case AVESLG: - return op_VESL, 3, 0 - case AVESRA: - return op_VESRA, 0, 0 - case AVESRAB: - return op_VESRA, 0, 0 - case AVESRAH: - return op_VESRA, 1, 0 - case AVESRAF: - return op_VESRA, 2, 0 - case AVESRAG: - return op_VESRA, 3, 0 - case AVESRAV: - return op_VESRAV, 0, 0 - case AVESRAVB: - return op_VESRAV, 0, 0 - case AVESRAVH: - return op_VESRAV, 1, 0 - case AVESRAVF: - return op_VESRAV, 2, 0 - case AVESRAVG: - return op_VESRAV, 3, 0 - case AVESRL: - return op_VESRL, 0, 0 - case AVESRLB: - return op_VESRL, 0, 0 - case AVESRLH: - return op_VESRL, 1, 0 - case AVESRLF: - return op_VESRL, 2, 0 - case AVESRLG: - return op_VESRL, 3, 0 - case AVESRLV: - return op_VESRLV, 0, 0 - case AVESRLVB: - return op_VESRLV, 0, 0 - case AVESRLVH: - return op_VESRLV, 1, 0 - case AVESRLVF: - return op_VESRLV, 2, 0 - case AVESRLVG: - return op_VESRLV, 3, 0 - case AVX: - return op_VX, 0, 0 - case AVFAE: - return op_VFAE, 0, 0 - case AVFAEB: - return op_VFAE, 0, 0 - case AVFAEH: - return op_VFAE, 1, 0 - case AVFAEF: - return op_VFAE, 2, 0 - case AVFAEBS: - return op_VFAE, 0, 1 - case AVFAEHS: - return op_VFAE, 1, 1 - case AVFAEFS: - return op_VFAE, 2, 1 - case AVFAEZB: - return op_VFAE, 0, 2 - case AVFAEZH: - return op_VFAE, 1, 2 - case AVFAEZF: - return op_VFAE, 2, 2 - case AVFAEZBS: - return op_VFAE, 0, 3 - case AVFAEZHS: - return op_VFAE, 1, 3 - case AVFAEZFS: - return op_VFAE, 2, 3 - case AVFEE: - return op_VFEE, 0, 0 - case AVFEEB: - return op_VFEE, 0, 0 - case AVFEEH: - return op_VFEE, 1, 0 - case AVFEEF: - return op_VFEE, 2, 0 - case AVFEEBS: - return op_VFEE, 0, 1 - case AVFEEHS: - return op_VFEE, 1, 1 - case AVFEEFS: - return op_VFEE, 2, 1 - case AVFEEZB: - return op_VFEE, 0, 2 - case AVFEEZH: - return op_VFEE, 1, 2 - case AVFEEZF: - return op_VFEE, 2, 2 - case AVFEEZBS: - return op_VFEE, 0, 3 - case AVFEEZHS: - return op_VFEE, 1, 3 - case AVFEEZFS: - return op_VFEE, 2, 3 - case AVFENE: - return op_VFENE, 0, 0 - case AVFENEB: - return op_VFENE, 0, 0 - case AVFENEH: - return op_VFENE, 1, 0 - case AVFENEF: - return op_VFENE, 2, 0 - case AVFENEBS: - return op_VFENE, 0, 1 - case AVFENEHS: - return op_VFENE, 1, 1 - case AVFENEFS: - return op_VFENE, 2, 1 - case AVFENEZB: - return op_VFENE, 0, 2 - case AVFENEZH: - return op_VFENE, 1, 2 - case AVFENEZF: - return op_VFENE, 2, 2 - case AVFENEZBS: - return op_VFENE, 0, 3 - case AVFENEZHS: - return op_VFENE, 1, 3 - case AVFENEZFS: - return op_VFENE, 2, 3 - case AVFA: - return op_VFA, 0, 0 - case AVFADB: - return op_VFA, 3, 0 - case AWFADB: - return op_VFA, 3, 0 - case AWFK: - return op_WFK, 0, 0 - case AWFKDB: - return op_WFK, 3, 0 - case AVFCE: - return op_VFCE, 0, 0 - case AVFCEDB: - return op_VFCE, 3, 0 - case AVFCEDBS: - return op_VFCE, 3, 1 - case AWFCEDB: - return op_VFCE, 3, 0 - case AWFCEDBS: - return op_VFCE, 3, 1 - case AVFCH: - return op_VFCH, 0, 0 - case AVFCHDB: - return op_VFCH, 3, 0 - case AVFCHDBS: - return op_VFCH, 3, 1 - case AWFCHDB: - return op_VFCH, 3, 0 - case AWFCHDBS: - return op_VFCH, 3, 1 - case AVFCHE: - return op_VFCHE, 0, 0 - case AVFCHEDB: - return op_VFCHE, 3, 0 - case AVFCHEDBS: - return op_VFCHE, 3, 1 - case AWFCHEDB: - return op_VFCHE, 3, 0 - case AWFCHEDBS: - return op_VFCHE, 3, 1 - case AWFC: - return op_WFC, 0, 0 - case AWFCDB: - return op_WFC, 3, 0 - case AVCDG: - return op_VCDG, 0, 0 - case AVCDGB: - return op_VCDG, 3, 0 - case AWCDGB: - return op_VCDG, 3, 0 - case AVCDLG: - return op_VCDLG, 0, 0 - case AVCDLGB: - return op_VCDLG, 3, 0 - case AWCDLGB: - return op_VCDLG, 3, 0 - case AVCGD: - return op_VCGD, 0, 0 - case AVCGDB: - return op_VCGD, 3, 0 - case AWCGDB: - return op_VCGD, 3, 0 - case AVCLGD: - return op_VCLGD, 0, 0 - case AVCLGDB: - return op_VCLGD, 3, 0 - case AWCLGDB: - return op_VCLGD, 3, 0 - case AVFD: - return op_VFD, 0, 0 - case AVFDDB: - return op_VFD, 3, 0 - case AWFDDB: - return op_VFD, 3, 0 - case AVLDE: - return op_VLDE, 0, 0 - case AVLDEB: - return op_VLDE, 2, 0 - case AWLDEB: - return op_VLDE, 2, 0 - case AVLED: - return op_VLED, 0, 0 - case AVLEDB: - return op_VLED, 3, 0 - case AWLEDB: - return op_VLED, 3, 0 - case AVFM: - return op_VFM, 0, 0 - case AVFMDB: - return op_VFM, 3, 0 - case AWFMDB: - return op_VFM, 3, 0 - case AVFMA: - return op_VFMA, 0, 0 - case AVFMADB: - return op_VFMA, 3, 0 - case AWFMADB: - return op_VFMA, 3, 0 - case AVFMS: - return op_VFMS, 0, 0 - case AVFMSDB: - return op_VFMS, 3, 0 - case AWFMSDB: - return op_VFMS, 3, 0 - case AVFPSO: - return op_VFPSO, 0, 0 - case AVFPSODB: - return op_VFPSO, 3, 0 - case AWFPSODB: - return op_VFPSO, 3, 0 - case AVFLCDB: - return op_VFPSO, 3, 0 - case AWFLCDB: - return op_VFPSO, 3, 0 - case AVFLNDB: - return op_VFPSO, 3, 1 - case AWFLNDB: - return op_VFPSO, 3, 1 - case AVFLPDB: - return op_VFPSO, 3, 2 - case AWFLPDB: - return op_VFPSO, 3, 2 - case AVFSQ: - return op_VFSQ, 0, 0 - case AVFSQDB: - return op_VFSQ, 3, 0 - case AWFSQDB: - return op_VFSQ, 3, 0 - case AVFS: - return op_VFS, 0, 0 - case AVFSDB: - return op_VFS, 3, 0 - case AWFSDB: - return op_VFS, 3, 0 - case AVFTCI: - return op_VFTCI, 0, 0 - case AVFTCIDB: - return op_VFTCI, 3, 0 - case AWFTCIDB: - return op_VFTCI, 3, 0 - case AVGFM: - return op_VGFM, 0, 0 - case AVGFMB: - return op_VGFM, 0, 0 - case AVGFMH: - return op_VGFM, 1, 0 - case AVGFMF: - return op_VGFM, 2, 0 - case AVGFMG: - return op_VGFM, 3, 0 - case AVGFMA: - return op_VGFMA, 0, 0 - case AVGFMAB: - return op_VGFMA, 0, 0 - case AVGFMAH: - return op_VGFMA, 1, 0 - case AVGFMAF: - return op_VGFMA, 2, 0 - case AVGFMAG: - return op_VGFMA, 3, 0 - case AVGEF: - return op_VGEF, 0, 0 - case AVGEG: - return op_VGEG, 0, 0 - case AVGBM: - return op_VGBM, 0, 0 - case AVZERO: - return op_VGBM, 0, 0 - case AVONE: - return op_VGBM, 0, 0 - case AVGM: - return op_VGM, 0, 0 - case AVGMB: - return op_VGM, 0, 0 - case AVGMH: - return op_VGM, 1, 0 - case AVGMF: - return op_VGM, 2, 0 - case AVGMG: - return op_VGM, 3, 0 - case AVISTR: - return op_VISTR, 0, 0 - case AVISTRB: - return op_VISTR, 0, 0 - case AVISTRH: - return op_VISTR, 1, 0 - case AVISTRF: - return op_VISTR, 2, 0 - case AVISTRBS: - return op_VISTR, 0, 1 - case AVISTRHS: - return op_VISTR, 1, 1 - case AVISTRFS: - return op_VISTR, 2, 1 - case AVL: - return op_VL, 0, 0 - case AVLR: - return op_VLR, 0, 0 - case AVLREP: - return op_VLREP, 0, 0 - case AVLREPB: - return op_VLREP, 0, 0 - case AVLREPH: - return op_VLREP, 1, 0 - case AVLREPF: - return op_VLREP, 2, 0 - case AVLREPG: - return op_VLREP, 3, 0 - case AVLC: - return op_VLC, 0, 0 - case AVLCB: - return op_VLC, 0, 0 - case AVLCH: - return op_VLC, 1, 0 - case AVLCF: - return op_VLC, 2, 0 - case AVLCG: - return op_VLC, 3, 0 - case AVLEH: - return op_VLEH, 0, 0 - case AVLEF: - return op_VLEF, 0, 0 - case AVLEG: - return op_VLEG, 0, 0 - case AVLEB: - return op_VLEB, 0, 0 - case AVLEIH: - return op_VLEIH, 0, 0 - case AVLEIF: - return op_VLEIF, 0, 0 - case AVLEIG: - return op_VLEIG, 0, 0 - case AVLEIB: - return op_VLEIB, 0, 0 - case AVFI: - return op_VFI, 0, 0 - case AVFIDB: - return op_VFI, 3, 0 - case AWFIDB: - return op_VFI, 3, 0 - case AVLGV: - return op_VLGV, 0, 0 - case AVLGVB: - return op_VLGV, 0, 0 - case AVLGVH: - return op_VLGV, 1, 0 - case AVLGVF: - return op_VLGV, 2, 0 - case AVLGVG: - return op_VLGV, 3, 0 - case AVLLEZ: - return op_VLLEZ, 0, 0 - case AVLLEZB: - return op_VLLEZ, 0, 0 - case AVLLEZH: - return op_VLLEZ, 1, 0 - case AVLLEZF: - return op_VLLEZ, 2, 0 - case AVLLEZG: - return op_VLLEZ, 3, 0 - case AVLM: - return op_VLM, 0, 0 - case AVLP: - return op_VLP, 0, 0 - case AVLPB: - return op_VLP, 0, 0 - case AVLPH: - return op_VLP, 1, 0 - case AVLPF: - return op_VLP, 2, 0 - case AVLPG: - return op_VLP, 3, 0 - case AVLBB: - return op_VLBB, 0, 0 - case AVLVG: - return op_VLVG, 0, 0 - case AVLVGB: - return op_VLVG, 0, 0 - case AVLVGH: - return op_VLVG, 1, 0 - case AVLVGF: - return op_VLVG, 2, 0 - case AVLVGG: - return op_VLVG, 3, 0 - case AVLVGP: - return op_VLVGP, 0, 0 - case AVLL: - return op_VLL, 0, 0 - case AVMX: - return op_VMX, 0, 0 - case AVMXB: - return op_VMX, 0, 0 - case AVMXH: - return op_VMX, 1, 0 - case AVMXF: - return op_VMX, 2, 0 - case AVMXG: - return op_VMX, 3, 0 - case AVMXL: - return op_VMXL, 0, 0 - case AVMXLB: - return op_VMXL, 0, 0 - case AVMXLH: - return op_VMXL, 1, 0 - case AVMXLF: - return op_VMXL, 2, 0 - case AVMXLG: - return op_VMXL, 3, 0 - case AVMRH: - return op_VMRH, 0, 0 - case AVMRHB: - return op_VMRH, 0, 0 - case AVMRHH: - return op_VMRH, 1, 0 - case AVMRHF: - return op_VMRH, 2, 0 - case AVMRHG: - return op_VMRH, 3, 0 - case AVMRL: - return op_VMRL, 0, 0 - case AVMRLB: - return op_VMRL, 0, 0 - case AVMRLH: - return op_VMRL, 1, 0 - case AVMRLF: - return op_VMRL, 2, 0 - case AVMRLG: - return op_VMRL, 3, 0 - case AVMN: - return op_VMN, 0, 0 - case AVMNB: - return op_VMN, 0, 0 - case AVMNH: - return op_VMN, 1, 0 - case AVMNF: - return op_VMN, 2, 0 - case AVMNG: - return op_VMN, 3, 0 - case AVMNL: - return op_VMNL, 0, 0 - case AVMNLB: - return op_VMNL, 0, 0 - case AVMNLH: - return op_VMNL, 1, 0 - case AVMNLF: - return op_VMNL, 2, 0 - case AVMNLG: - return op_VMNL, 3, 0 - case AVMAE: - return op_VMAE, 0, 0 - case AVMAEB: - return op_VMAE, 0, 0 - case AVMAEH: - return op_VMAE, 1, 0 - case AVMAEF: - return op_VMAE, 2, 0 - case AVMAH: - return op_VMAH, 0, 0 - case AVMAHB: - return op_VMAH, 0, 0 - case AVMAHH: - return op_VMAH, 1, 0 - case AVMAHF: - return op_VMAH, 2, 0 - case AVMALE: - return op_VMALE, 0, 0 - case AVMALEB: - return op_VMALE, 0, 0 - case AVMALEH: - return op_VMALE, 1, 0 - case AVMALEF: - return op_VMALE, 2, 0 - case AVMALH: - return op_VMALH, 0, 0 - case AVMALHB: - return op_VMALH, 0, 0 - case AVMALHH: - return op_VMALH, 1, 0 - case AVMALHF: - return op_VMALH, 2, 0 - case AVMALO: - return op_VMALO, 0, 0 - case AVMALOB: - return op_VMALO, 0, 0 - case AVMALOH: - return op_VMALO, 1, 0 - case AVMALOF: - return op_VMALO, 2, 0 - case AVMAL: - return op_VMAL, 0, 0 - case AVMALB: - return op_VMAL, 0, 0 - case AVMALHW: - return op_VMAL, 1, 0 - case AVMALF: - return op_VMAL, 2, 0 - case AVMAO: - return op_VMAO, 0, 0 - case AVMAOB: - return op_VMAO, 0, 0 - case AVMAOH: - return op_VMAO, 1, 0 - case AVMAOF: - return op_VMAO, 2, 0 - case AVME: - return op_VME, 0, 0 - case AVMEB: - return op_VME, 0, 0 - case AVMEH: - return op_VME, 1, 0 - case AVMEF: - return op_VME, 2, 0 - case AVMH: - return op_VMH, 0, 0 - case AVMHB: - return op_VMH, 0, 0 - case AVMHH: - return op_VMH, 1, 0 - case AVMHF: - return op_VMH, 2, 0 - case AVMLE: - return op_VMLE, 0, 0 - case AVMLEB: - return op_VMLE, 0, 0 - case AVMLEH: - return op_VMLE, 1, 0 - case AVMLEF: - return op_VMLE, 2, 0 - case AVMLH: - return op_VMLH, 0, 0 - case AVMLHB: - return op_VMLH, 0, 0 - case AVMLHH: - return op_VMLH, 1, 0 - case AVMLHF: - return op_VMLH, 2, 0 - case AVMLO: - return op_VMLO, 0, 0 - case AVMLOB: - return op_VMLO, 0, 0 - case AVMLOH: - return op_VMLO, 1, 0 - case AVMLOF: - return op_VMLO, 2, 0 - case AVML: - return op_VML, 0, 0 - case AVMLB: - return op_VML, 0, 0 - case AVMLHW: - return op_VML, 1, 0 - case AVMLF: - return op_VML, 2, 0 - case AVMO: - return op_VMO, 0, 0 - case AVMOB: - return op_VMO, 0, 0 - case AVMOH: - return op_VMO, 1, 0 - case AVMOF: - return op_VMO, 2, 0 - case AVNO: - return op_VNO, 0, 0 - case AVNOT: - return op_VNO, 0, 0 - case AVO: - return op_VO, 0, 0 - case AVPK: - return op_VPK, 0, 0 - case AVPKH: - return op_VPK, 1, 0 - case AVPKF: - return op_VPK, 2, 0 - case AVPKG: - return op_VPK, 3, 0 - case AVPKLS: - return op_VPKLS, 0, 0 - case AVPKLSH: - return op_VPKLS, 1, 0 - case AVPKLSF: - return op_VPKLS, 2, 0 - case AVPKLSG: - return op_VPKLS, 3, 0 - case AVPKLSHS: - return op_VPKLS, 1, 1 - case AVPKLSFS: - return op_VPKLS, 2, 1 - case AVPKLSGS: - return op_VPKLS, 3, 1 - case AVPKS: - return op_VPKS, 0, 0 - case AVPKSH: - return op_VPKS, 1, 0 - case AVPKSF: - return op_VPKS, 2, 0 - case AVPKSG: - return op_VPKS, 3, 0 - case AVPKSHS: - return op_VPKS, 1, 1 - case AVPKSFS: - return op_VPKS, 2, 1 - case AVPKSGS: - return op_VPKS, 3, 1 - case AVPERM: - return op_VPERM, 0, 0 - case AVPDI: - return op_VPDI, 0, 0 - case AVPOPCT: - return op_VPOPCT, 0, 0 - case AVREP: - return op_VREP, 0, 0 - case AVREPB: - return op_VREP, 0, 0 - case AVREPH: - return op_VREP, 1, 0 - case AVREPF: - return op_VREP, 2, 0 - case AVREPG: - return op_VREP, 3, 0 - case AVREPI: - return op_VREPI, 0, 0 - case AVREPIB: - return op_VREPI, 0, 0 - case AVREPIH: - return op_VREPI, 1, 0 - case AVREPIF: - return op_VREPI, 2, 0 - case AVREPIG: - return op_VREPI, 3, 0 - case AVSCEF: - return op_VSCEF, 0, 0 - case AVSCEG: - return op_VSCEG, 0, 0 - case AVSEL: - return op_VSEL, 0, 0 - case AVSL: - return op_VSL, 0, 0 - case AVSLB: - return op_VSLB, 0, 0 - case AVSLDB: - return op_VSLDB, 0, 0 - case AVSRA: - return op_VSRA, 0, 0 - case AVSRAB: - return op_VSRAB, 0, 0 - case AVSRL: - return op_VSRL, 0, 0 - case AVSRLB: - return op_VSRLB, 0, 0 - case AVSEG: - return op_VSEG, 0, 0 - case AVSEGB: - return op_VSEG, 0, 0 - case AVSEGH: - return op_VSEG, 1, 0 - case AVSEGF: - return op_VSEG, 2, 0 - case AVST: - return op_VST, 0, 0 - case AVSTEH: - return op_VSTEH, 0, 0 - case AVSTEF: - return op_VSTEF, 0, 0 - case AVSTEG: - return op_VSTEG, 0, 0 - case AVSTEB: - return op_VSTEB, 0, 0 - case AVSTM: - return op_VSTM, 0, 0 - case AVSTL: - return op_VSTL, 0, 0 - case AVSTRC: - return op_VSTRC, 0, 0 - case AVSTRCB: - return op_VSTRC, 0, 0 - case AVSTRCH: - return op_VSTRC, 1, 0 - case AVSTRCF: - return op_VSTRC, 2, 0 - case AVSTRCBS: - return op_VSTRC, 0, 1 - case AVSTRCHS: - return op_VSTRC, 1, 1 - case AVSTRCFS: - return op_VSTRC, 2, 1 - case AVSTRCZB: - return op_VSTRC, 0, 2 - case AVSTRCZH: - return op_VSTRC, 1, 2 - case AVSTRCZF: - return op_VSTRC, 2, 2 - case AVSTRCZBS: - return op_VSTRC, 0, 3 - case AVSTRCZHS: - return op_VSTRC, 1, 3 - case AVSTRCZFS: - return op_VSTRC, 2, 3 - case AVS: - return op_VS, 0, 0 - case AVSB: - return op_VS, 0, 0 - case AVSH: - return op_VS, 1, 0 - case AVSF: - return op_VS, 2, 0 - case AVSG: - return op_VS, 3, 0 - case AVSQ: - return op_VS, 4, 0 - case AVSCBI: - return op_VSCBI, 0, 0 - case AVSCBIB: - return op_VSCBI, 0, 0 - case AVSCBIH: - return op_VSCBI, 1, 0 - case AVSCBIF: - return op_VSCBI, 2, 0 - case AVSCBIG: - return op_VSCBI, 3, 0 - case AVSCBIQ: - return op_VSCBI, 4, 0 - case AVSBCBI: - return op_VSBCBI, 0, 0 - case AVSBCBIQ: - return op_VSBCBI, 4, 0 - case AVSBI: - return op_VSBI, 0, 0 - case AVSBIQ: - return op_VSBI, 4, 0 - case AVSUMG: - return op_VSUMG, 0, 0 - case AVSUMGH: - return op_VSUMG, 1, 0 - case AVSUMGF: - return op_VSUMG, 2, 0 - case AVSUMQ: - return op_VSUMQ, 0, 0 - case AVSUMQF: - return op_VSUMQ, 1, 0 - case AVSUMQG: - return op_VSUMQ, 2, 0 - case AVSUM: - return op_VSUM, 0, 0 - case AVSUMB: - return op_VSUM, 0, 0 - case AVSUMH: - return op_VSUM, 1, 0 - case AVTM: - return op_VTM, 0, 0 - case AVUPH: - return op_VUPH, 0, 0 - case AVUPHB: - return op_VUPH, 0, 0 - case AVUPHH: - return op_VUPH, 1, 0 - case AVUPHF: - return op_VUPH, 2, 0 - case AVUPLH: - return op_VUPLH, 0, 0 - case AVUPLHB: - return op_VUPLH, 0, 0 - case AVUPLHH: - return op_VUPLH, 1, 0 - case AVUPLHF: - return op_VUPLH, 2, 0 - case AVUPLL: - return op_VUPLL, 0, 0 - case AVUPLLB: - return op_VUPLL, 0, 0 - case AVUPLLH: - return op_VUPLL, 1, 0 - case AVUPLLF: - return op_VUPLL, 2, 0 - case AVUPL: - return op_VUPL, 0, 0 - case AVUPLB: - return op_VUPL, 0, 0 - case AVUPLHW: - return op_VUPL, 1, 0 - case AVUPLF: - return op_VUPL, 2, 0 - } -} - -// singleElementMask returns the single element mask bits required for the -// given instruction. -func singleElementMask(as obj.As) uint32 { - switch as { - case AWFADB, - AWFK, - AWFKDB, - AWFCEDB, - AWFCEDBS, - AWFCHDB, - AWFCHDBS, - AWFCHEDB, - AWFCHEDBS, - AWFC, - AWFCDB, - AWCDGB, - AWCDLGB, - AWCGDB, - AWCLGDB, - AWFDDB, - AWLDEB, - AWLEDB, - AWFMDB, - AWFMADB, - AWFMSDB, - AWFPSODB, - AWFLCDB, - AWFLNDB, - AWFLPDB, - AWFSQDB, - AWFSDB, - AWFTCIDB, - AWFIDB: - return 8 - } - return 0 -} diff --git a/vendor/github.com/google/gops/internal/obj/stack.go b/vendor/github.com/google/gops/internal/obj/stack.go deleted file mode 100644 index 687adf20..00000000 --- a/vendor/github.com/google/gops/internal/obj/stack.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2011 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 obj - -// For the linkers. Must match Go definitions. -// TODO(rsc): Share Go definitions with linkers directly. - -const ( - STACKSYSTEM = 0 - StackSystem = STACKSYSTEM - StackBig = 4096 - StackGuard = 880*stackGuardMultiplier + StackSystem - StackSmall = 128 - StackLimit = StackGuard - StackSystem - StackSmall -) - -const ( - StackPreempt = -1314 // 0xfff...fade -) diff --git a/vendor/github.com/google/gops/internal/obj/stringer.go b/vendor/github.com/google/gops/internal/obj/stringer.go deleted file mode 100644 index 2ba213e5..00000000 --- a/vendor/github.com/google/gops/internal/obj/stringer.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2015 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. - -// +build ignore - -// This is a mini version of the stringer tool customized for the Anames table -// in the architecture support for obj. -// This version just generates the slice of strings, not the String method. - -package main - -import ( - "bufio" - "flag" - "fmt" - "log" - "os" - "regexp" - "strings" -) - -var ( - input = flag.String("i", "", "input file name") - output = flag.String("o", "", "output file name") - pkg = flag.String("p", "", "package name") -) - -var Are = regexp.MustCompile(`^\tA([A-Z0-9]+)`) - -func main() { - flag.Parse() - if *input == "" || *output == "" || *pkg == "" { - flag.Usage() - os.Exit(2) - } - in, err := os.Open(*input) - if err != nil { - log.Fatal(err) - } - fd, err := os.Create(*output) - if err != nil { - log.Fatal(err) - } - out := bufio.NewWriter(fd) - defer out.Flush() - var on = false - s := bufio.NewScanner(in) - first := true - for s.Scan() { - line := s.Text() - if !on { - // First relevant line contains "= obj.ABase". - // If we find it, delete the = so we don't stop immediately. - const prefix = "= obj.ABase" - index := strings.Index(line, prefix) - if index < 0 { - continue - } - // It's on. Start with the header. - fmt.Fprintf(out, header, *input, *output, *pkg, *pkg) - on = true - line = line[:index] - } - // Strip comments so their text won't defeat our heuristic. - index := strings.Index(line, "//") - if index > 0 { - line = line[:index] - } - index = strings.Index(line, "/*") - if index > 0 { - line = line[:index] - } - // Termination condition: Any line with an = changes the sequence, - // so stop there, and stop at a closing brace. - if strings.HasPrefix(line, "}") || strings.ContainsRune(line, '=') { - break - } - sub := Are.FindStringSubmatch(line) - if len(sub) < 2 { - continue - } - if first { - fmt.Fprintf(out, "\tobj.A_ARCHSPECIFIC: %q,\n", sub[1]) - first = false - } else { - fmt.Fprintf(out, "\t%q,\n", sub[1]) - } - } - fmt.Fprintln(out, "}") - if s.Err() != nil { - log.Fatal(err) - } -} - -const header = `// Generated by stringer -i %s -o %s -p %s -// Do not edit. - -package %s - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ -` diff --git a/vendor/github.com/google/gops/internal/obj/sym.go b/vendor/github.com/google/gops/internal/obj/sym.go deleted file mode 100644 index 84de5b61..00000000 --- a/vendor/github.com/google/gops/internal/obj/sym.go +++ /dev/null @@ -1,88 +0,0 @@ -// Derived from Inferno utils/6l/obj.c and utils/6l/span.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package obj - -import ( - "log" - "os" - "path/filepath" -) - -func Linknew(arch *LinkArch) *Link { - ctxt := new(Link) - ctxt.Hash = make(map[SymVer]*LSym) - ctxt.Arch = arch - ctxt.Version = HistVersion - - var buf string - buf, _ = os.Getwd() - if buf == "" { - buf = "/???" - } - buf = filepath.ToSlash(buf) - ctxt.Pathname = buf - - ctxt.LineHist.GOROOT = GOROOT - ctxt.LineHist.Dir = ctxt.Pathname - - ctxt.Headtype.Set(GOOS) - if ctxt.Headtype < 0 { - log.Fatalf("unknown goos %s", GOOS) - } - - ctxt.Flag_optimize = true - ctxt.Framepointer_enabled = Framepointer_enabled(GOOS, arch.Name) - return ctxt -} - -func Linklookup(ctxt *Link, name string, v int) *LSym { - s := ctxt.Hash[SymVer{name, v}] - if s != nil { - return s - } - - s = &LSym{ - Name: name, - Type: 0, - Version: int16(v), - Size: 0, - } - ctxt.Hash[SymVer{name, v}] = s - return s -} - -func Linksymfmt(s *LSym) string { - if s == nil { - return "" - } - return s.Name -} diff --git a/vendor/github.com/google/gops/internal/obj/symkind_string.go b/vendor/github.com/google/gops/internal/obj/symkind_string.go deleted file mode 100644 index fef8c355..00000000 --- a/vendor/github.com/google/gops/internal/obj/symkind_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by "stringer -type=SymKind"; DO NOT EDIT - -package obj - -import "fmt" - -const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILESFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFO" - -var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 214, 220, 229, 237, 244, 254, 262, 267, 271, 280, 287, 292, 304, 316, 333, 350, 355, 364, 370, 380, 388, 398, 408} - -func (i SymKind) String() string { - if i < 0 || i >= SymKind(len(_SymKind_index)-1) { - return fmt.Sprintf("SymKind(%d)", i) - } - return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]] -} diff --git a/vendor/github.com/google/gops/internal/obj/textflag.go b/vendor/github.com/google/gops/internal/obj/textflag.go deleted file mode 100644 index d8a52da4..00000000 --- a/vendor/github.com/google/gops/internal/obj/textflag.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 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. - -// This file defines flags attached to various functions -// and data objects. The compilers, assemblers, and linker must -// all agree on these values. - -package obj - -const ( - // Don't profile the marked routine. - // - // Deprecated: Not implemented, do not use. - NOPROF = 1 - - // It is ok for the linker to get multiple of these symbols. It will - // pick one of the duplicates to use. - DUPOK = 2 - - // Don't insert stack check preamble. - NOSPLIT = 4 - - // Put this data in a read-only section. - RODATA = 8 - - // This data contains no pointers. - NOPTR = 16 - - // This is a wrapper function and should not count as disabling 'recover'. - WRAPPER = 32 - - // This function uses its incoming context register. - NEEDCTXT = 64 - - // When passed to ggloblsym, causes Local to be set to true on the LSym it creates. - LOCAL = 128 - - // Allocate a word of thread local storage and store the offset from the - // thread local base to the thread local storage in this variable. - TLSBSS = 256 - - // Do not insert instructions to allocate a stack frame for this function. - // Only valid on functions that declare a frame size of 0. - // TODO(mwhudson): only implemented for ppc64x at present. - NOFRAME = 512 - - // Function can call reflect.Type.Method or reflect.Type.MethodByName. - REFLECTMETHOD = 1024 -) diff --git a/vendor/github.com/google/gops/internal/obj/typekind.go b/vendor/github.com/google/gops/internal/obj/typekind.go deleted file mode 100644 index 21932716..00000000 --- a/vendor/github.com/google/gops/internal/obj/typekind.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2012 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 obj - -// Must match runtime and reflect. -// Included by cmd/gc. - -const ( - KindBool = 1 + iota - KindInt - KindInt8 - KindInt16 - KindInt32 - KindInt64 - KindUint - KindUint8 - KindUint16 - KindUint32 - KindUint64 - KindUintptr - KindFloat32 - KindFloat64 - KindComplex64 - KindComplex128 - KindArray - KindChan - KindFunc - KindInterface - KindMap - KindPtr - KindSlice - KindString - KindStruct - KindUnsafePointer - KindDirectIface = 1 << 5 - KindGCProg = 1 << 6 - KindNoPointers = 1 << 7 - KindMask = (1 << 5) - 1 -) diff --git a/vendor/github.com/google/gops/internal/obj/util.go b/vendor/github.com/google/gops/internal/obj/util.go deleted file mode 100644 index 9f1c6f08..00000000 --- a/vendor/github.com/google/gops/internal/obj/util.go +++ /dev/null @@ -1,499 +0,0 @@ -// Copyright 2015 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 obj - -import ( - "bytes" - "fmt" - "log" - "os" - "strings" - "time" -) - -const REG_NONE = 0 - -var start time.Time - -func Cputime() float64 { - if start.IsZero() { - start = time.Now() - } - return time.Since(start).Seconds() -} - -func envOr(key, value string) string { - if x := os.Getenv(key); x != "" { - return x - } - return value -} - -var ( - GOROOT = envOr("GOROOT", defaultGOROOT) - GOARCH = envOr("GOARCH", defaultGOARCH) - GOOS = envOr("GOOS", defaultGOOS) - GO386 = envOr("GO386", defaultGO386) - GOARM = goarm() - Version = version -) - -func goarm() int { - switch v := envOr("GOARM", defaultGOARM); v { - case "5": - return 5 - case "6": - return 6 - case "7": - return 7 - } - // Fail here, rather than validate at multiple call sites. - log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.") - panic("unreachable") -} - -func Getgoextlinkenabled() string { - return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED) -} - -func (p *Prog) Line() string { - return p.Ctxt.LineHist.LineString(int(p.Lineno)) -} - -var armCondCode = []string{ - ".EQ", - ".NE", - ".CS", - ".CC", - ".MI", - ".PL", - ".VS", - ".VC", - ".HI", - ".LS", - ".GE", - ".LT", - ".GT", - ".LE", - "", - ".NV", -} - -/* ARM scond byte */ -const ( - C_SCOND = (1 << 4) - 1 - C_SBIT = 1 << 4 - C_PBIT = 1 << 5 - C_WBIT = 1 << 6 - C_FBIT = 1 << 7 - C_UBIT = 1 << 7 - C_SCOND_XOR = 14 -) - -// CConv formats ARM condition codes. -func CConv(s uint8) string { - if s == 0 { - return "" - } - sc := armCondCode[(s&C_SCOND)^C_SCOND_XOR] - if s&C_SBIT != 0 { - sc += ".S" - } - if s&C_PBIT != 0 { - sc += ".P" - } - if s&C_WBIT != 0 { - sc += ".W" - } - if s&C_UBIT != 0 { /* ambiguous with FBIT */ - sc += ".U" - } - return sc -} - -func (p *Prog) String() string { - if p == nil { - return "" - } - - if p.Ctxt == nil { - return "" - } - - sc := CConv(p.Scond) - - var buf bytes.Buffer - - fmt.Fprintf(&buf, "%.5d (%v)\t%v%s", p.Pc, p.Line(), p.As, sc) - sep := "\t" - quadOpAmd64 := p.RegTo2 == -1 - if quadOpAmd64 { - fmt.Fprintf(&buf, "%s$%d", sep, p.From3.Offset) - sep = ", " - } - if p.From.Type != TYPE_NONE { - fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.From)) - sep = ", " - } - if p.Reg != REG_NONE { - // Should not happen but might as well show it if it does. - fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.Reg))) - sep = ", " - } - if p.From3Type() != TYPE_NONE { - if p.From3.Type == TYPE_CONST && p.As == ATEXT { - // Special case - omit $. - fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset) - } else if quadOpAmd64 { - fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg))) - } else { - fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3)) - } - sep = ", " - } - if p.To.Type != TYPE_NONE { - fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To)) - } - if p.RegTo2 != REG_NONE && !quadOpAmd64 { - fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.RegTo2))) - } - return buf.String() -} - -func (ctxt *Link) NewProg() *Prog { - var p *Prog - if i := ctxt.allocIdx; i < len(ctxt.progs) { - p = &ctxt.progs[i] - ctxt.allocIdx = i + 1 - } else { - p = new(Prog) // should be the only call to this; all others should use ctxt.NewProg - } - p.Ctxt = ctxt - return p -} -func (ctxt *Link) freeProgs() { - s := ctxt.progs[:ctxt.allocIdx] - for i := range s { - s[i] = Prog{} - } - ctxt.allocIdx = 0 -} - -func (ctxt *Link) Line(n int) string { - return ctxt.LineHist.LineString(n) -} - -func Getcallerpc(interface{}) uintptr { - return 1 -} - -func (ctxt *Link) Dconv(a *Addr) string { - return Dconv(nil, a) -} - -func Dconv(p *Prog, a *Addr) string { - var str string - - switch a.Type { - default: - str = fmt.Sprintf("type=%d", a.Type) - - case TYPE_NONE: - str = "" - if a.Name != NAME_NONE || a.Reg != 0 || a.Sym != nil { - str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg))) - } - - case TYPE_REG: - // TODO(rsc): This special case is for x86 instructions like - // PINSRQ CX,$1,X6 - // where the $1 is included in the p->to Addr. - // Move into a new field. - if a.Offset != 0 { - str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg))) - break - } - - str = Rconv(int(a.Reg)) - if a.Name != NAME_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg))) - } - - case TYPE_BRANCH: - if a.Sym != nil { - str = fmt.Sprintf("%s(SB)", a.Sym.Name) - } else if p != nil && p.Pcond != nil { - str = fmt.Sprint(p.Pcond.Pc) - } else if a.Val != nil { - str = fmt.Sprint(a.Val.(*Prog).Pc) - } else { - str = fmt.Sprintf("%d(PC)", a.Offset) - } - - case TYPE_INDIR: - str = fmt.Sprintf("*%s", Mconv(a)) - - case TYPE_MEM: - str = Mconv(a) - if a.Index != REG_NONE { - str += fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) - } - - case TYPE_CONST: - if a.Reg != 0 { - str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg))) - } else { - str = fmt.Sprintf("$%v", Mconv(a)) - } - - case TYPE_TEXTSIZE: - if a.Val.(int32) == ArgsSizeUnknown { - str = fmt.Sprintf("$%d", a.Offset) - } else { - str = fmt.Sprintf("$%d-%d", a.Offset, a.Val.(int32)) - } - - case TYPE_FCONST: - str = fmt.Sprintf("%.17g", a.Val.(float64)) - // Make sure 1 prints as 1.0 - if !strings.ContainsAny(str, ".e") { - str += ".0" - } - str = fmt.Sprintf("$(%s)", str) - - case TYPE_SCONST: - str = fmt.Sprintf("$%q", a.Val.(string)) - - case TYPE_ADDR: - str = fmt.Sprintf("$%s", Mconv(a)) - - case TYPE_SHIFT: - v := int(a.Offset) - ops := "<<>>->@>" - switch GOARCH { - case "arm": - op := ops[((v>>5)&3)<<1:] - if v&(1<<4) != 0 { - str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15) - } else { - str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31) - } - if a.Reg != 0 { - str += fmt.Sprintf("(%v)", Rconv(int(a.Reg))) - } - case "arm64": - op := ops[((v>>22)&3)<<1:] - str = fmt.Sprintf("R%d%c%c%d", (v>>16)&31, op[0], op[1], (v>>10)&63) - default: - panic("TYPE_SHIFT is not supported on " + GOARCH) - } - - case TYPE_REGREG: - str = fmt.Sprintf("(%v, %v)", Rconv(int(a.Reg)), Rconv(int(a.Offset))) - - case TYPE_REGREG2: - str = fmt.Sprintf("%v, %v", Rconv(int(a.Reg)), Rconv(int(a.Offset))) - - case TYPE_REGLIST: - str = regListConv(int(a.Offset)) - } - - return str -} - -func Mconv(a *Addr) string { - var str string - - switch a.Name { - default: - str = fmt.Sprintf("name=%d", a.Name) - - case NAME_NONE: - switch { - case a.Reg == REG_NONE: - str = fmt.Sprint(a.Offset) - case a.Offset == 0: - str = fmt.Sprintf("(%v)", Rconv(int(a.Reg))) - case a.Offset != 0: - str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg))) - } - - case NAME_EXTERN: - if a.Sym != nil { - str = fmt.Sprintf("%s%s(SB)", a.Sym.Name, offConv(a.Offset)) - } else { - str = fmt.Sprintf("%s(SB)", offConv(a.Offset)) - } - - case NAME_GOTREF: - if a.Sym != nil { - str = fmt.Sprintf("%s%s@GOT(SB)", a.Sym.Name, offConv(a.Offset)) - } else { - str = fmt.Sprintf("%s@GOT(SB)", offConv(a.Offset)) - } - - case NAME_STATIC: - if a.Sym != nil { - str = fmt.Sprintf("%s<>%s(SB)", a.Sym.Name, offConv(a.Offset)) - } else { - str = fmt.Sprintf("<>%s(SB)", offConv(a.Offset)) - } - - case NAME_AUTO: - if a.Sym != nil { - str = fmt.Sprintf("%s%s(SP)", a.Sym.Name, offConv(a.Offset)) - } else { - str = fmt.Sprintf("%s(SP)", offConv(a.Offset)) - } - - case NAME_PARAM: - if a.Sym != nil { - str = fmt.Sprintf("%s%s(FP)", a.Sym.Name, offConv(a.Offset)) - } else { - str = fmt.Sprintf("%s(FP)", offConv(a.Offset)) - } - } - return str -} - -func offConv(off int64) string { - if off == 0 { - return "" - } - return fmt.Sprintf("%+d", off) -} - -type regSet struct { - lo int - hi int - Rconv func(int) string -} - -// Few enough architectures that a linear scan is fastest. -// Not even worth sorting. -var regSpace []regSet - -/* - Each architecture defines a register space as a unique - integer range. - Here is the list of architectures and the base of their register spaces. -*/ - -const ( - // Because of masking operations in the encodings, each register - // space should start at 0 modulo some power of 2. - RBase386 = 1 * 1024 - RBaseAMD64 = 2 * 1024 - RBaseARM = 3 * 1024 - RBasePPC64 = 4 * 1024 // range [4k, 8k) - RBaseARM64 = 8 * 1024 // range [8k, 13k) - RBaseMIPS64 = 13 * 1024 // range [13k, 14k) - RBaseS390X = 14 * 1024 // range [14k, 15k) -) - -// RegisterRegister binds a pretty-printer (Rconv) for register -// numbers to a given register number range. Lo is inclusive, -// hi exclusive (valid registers are lo through hi-1). -func RegisterRegister(lo, hi int, Rconv func(int) string) { - regSpace = append(regSpace, regSet{lo, hi, Rconv}) -} - -func Rconv(reg int) string { - if reg == REG_NONE { - return "NONE" - } - for i := range regSpace { - rs := ®Space[i] - if rs.lo <= reg && reg < rs.hi { - return rs.Rconv(reg) - } - } - return fmt.Sprintf("R???%d", reg) -} - -func regListConv(list int) string { - str := "" - - for i := 0; i < 16; i++ { // TODO: 16 is ARM-specific. - if list&(1< AllowedOpCodes { - panic(fmt.Sprintf("too many instructions, have %d max %d", len(Anames), AllowedOpCodes)) - } - aSpace = append(aSpace, opSet{lo, Anames}) -} - -func (a As) String() string { - if 0 <= a && int(a) < len(Anames) { - return Anames[a] - } - for i := range aSpace { - as := &aSpace[i] - if as.lo <= a && int(a-as.lo) < len(as.names) { - return as.names[a-as.lo] - } - } - return fmt.Sprintf("A???%d", a) -} - -var Anames = []string{ - "XXX", - "CALL", - "DUFFCOPY", - "DUFFZERO", - "END", - "FUNCDATA", - "JMP", - "NOP", - "PCDATA", - "RET", - "TEXT", - "TYPE", - "UNDEF", - "USEFIELD", - "VARDEF", - "VARKILL", - "VARLIVE", -} - -func Bool2int(b bool) int { - // The compiler currently only optimizes this form. - // See issue 6011. - var i int - if b { - i = 1 - } else { - i = 0 - } - return i -} diff --git a/vendor/github.com/google/gops/internal/obj/x86/a.out.go b/vendor/github.com/google/gops/internal/obj/x86/a.out.go deleted file mode 100644 index 34480393..00000000 --- a/vendor/github.com/google/gops/internal/obj/x86/a.out.go +++ /dev/null @@ -1,1009 +0,0 @@ -// Inferno utils/6c/6.out.h -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6c/6.out.h -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package x86 - -import "github.com/google/gops/internal/obj" - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p x86 - -const ( - /* mark flags */ - DONE = 1 << iota - PRESERVEFLAGS // not allowed to clobber flags -) - -/* - * amd64 - */ -const ( - AAAA = obj.ABaseAMD64 + obj.A_ARCHSPECIFIC + iota - AAAD - AAAM - AAAS - AADCB - AADCL - AADCW - AADDB - AADDL - AADDW - AADJSP - AANDB - AANDL - AANDW - AARPL - ABOUNDL - ABOUNDW - ABSFL - ABSFW - ABSRL - ABSRW - ABTL - ABTW - ABTCL - ABTCW - ABTRL - ABTRW - ABTSL - ABTSW - ABYTE - ACLC - ACLD - ACLI - ACLTS - ACMC - ACMPB - ACMPL - ACMPW - ACMPSB - ACMPSL - ACMPSW - ADAA - ADAS - ADECB - ADECL - ADECQ - ADECW - ADIVB - ADIVL - ADIVW - AENTER - AHADDPD - AHADDPS - AHLT - AHSUBPD - AHSUBPS - AIDIVB - AIDIVL - AIDIVW - AIMULB - AIMULL - AIMULW - AINB - AINL - AINW - AINCB - AINCL - AINCQ - AINCW - AINSB - AINSL - AINSW - AINT - AINTO - AIRETL - AIRETW - AJCC // >= unsigned - AJCS // < unsigned - AJCXZL - AJEQ // == (zero) - AJGE // >= signed - AJGT // > signed - AJHI // > unsigned - AJLE // <= signed - AJLS // <= unsigned - AJLT // < signed - AJMI // sign bit set (negative) - AJNE // != (nonzero) - AJOC // overflow clear - AJOS // overflow set - AJPC // parity clear - AJPL // sign bit clear (positive) - AJPS // parity set - ALAHF - ALARL - ALARW - ALEAL - ALEAW - ALEAVEL - ALEAVEW - ALOCK - ALODSB - ALODSL - ALODSW - ALONG - ALOOP - ALOOPEQ - ALOOPNE - ALSLL - ALSLW - AMOVB - AMOVL - AMOVW - AMOVBLSX - AMOVBLZX - AMOVBQSX - AMOVBQZX - AMOVBWSX - AMOVBWZX - AMOVWLSX - AMOVWLZX - AMOVWQSX - AMOVWQZX - AMOVSB - AMOVSL - AMOVSW - AMULB - AMULL - AMULW - ANEGB - ANEGL - ANEGW - ANOTB - ANOTL - ANOTW - AORB - AORL - AORW - AOUTB - AOUTL - AOUTW - AOUTSB - AOUTSL - AOUTSW - APAUSE - APOPAL - APOPAW - APOPCNTW - APOPCNTL - APOPCNTQ - APOPFL - APOPFW - APOPL - APOPW - APUSHAL - APUSHAW - APUSHFL - APUSHFW - APUSHL - APUSHW - ARCLB - ARCLL - ARCLW - ARCRB - ARCRL - ARCRW - AREP - AREPN - AROLB - AROLL - AROLW - ARORB - ARORL - ARORW - ASAHF - ASALB - ASALL - ASALW - ASARB - ASARL - ASARW - ASBBB - ASBBL - ASBBW - ASCASB - ASCASL - ASCASW - ASETCC - ASETCS - ASETEQ - ASETGE - ASETGT - ASETHI - ASETLE - ASETLS - ASETLT - ASETMI - ASETNE - ASETOC - ASETOS - ASETPC - ASETPL - ASETPS - ACDQ - ACWD - ASHLB - ASHLL - ASHLW - ASHRB - ASHRL - ASHRW - ASTC - ASTD - ASTI - ASTOSB - ASTOSL - ASTOSW - ASUBB - ASUBL - ASUBW - ASYSCALL - ATESTB - ATESTL - ATESTW - AVERR - AVERW - AWAIT - AWORD - AXCHGB - AXCHGL - AXCHGW - AXLAT - AXORB - AXORL - AXORW - - AFMOVB - AFMOVBP - AFMOVD - AFMOVDP - AFMOVF - AFMOVFP - AFMOVL - AFMOVLP - AFMOVV - AFMOVVP - AFMOVW - AFMOVWP - AFMOVX - AFMOVXP - - AFCOMD - AFCOMDP - AFCOMDPP - AFCOMF - AFCOMFP - AFCOML - AFCOMLP - AFCOMW - AFCOMWP - AFUCOM - AFUCOMP - AFUCOMPP - - AFADDDP - AFADDW - AFADDL - AFADDF - AFADDD - - AFMULDP - AFMULW - AFMULL - AFMULF - AFMULD - - AFSUBDP - AFSUBW - AFSUBL - AFSUBF - AFSUBD - - AFSUBRDP - AFSUBRW - AFSUBRL - AFSUBRF - AFSUBRD - - AFDIVDP - AFDIVW - AFDIVL - AFDIVF - AFDIVD - - AFDIVRDP - AFDIVRW - AFDIVRL - AFDIVRF - AFDIVRD - - AFXCHD - AFFREE - - AFLDCW - AFLDENV - AFRSTOR - AFSAVE - AFSTCW - AFSTENV - AFSTSW - - AF2XM1 - AFABS - AFCHS - AFCLEX - AFCOS - AFDECSTP - AFINCSTP - AFINIT - AFLD1 - AFLDL2E - AFLDL2T - AFLDLG2 - AFLDLN2 - AFLDPI - AFLDZ - AFNOP - AFPATAN - AFPREM - AFPREM1 - AFPTAN - AFRNDINT - AFSCALE - AFSIN - AFSINCOS - AFSQRT - AFTST - AFXAM - AFXTRACT - AFYL2X - AFYL2XP1 - - // extra 32-bit operations - ACMPXCHGB - ACMPXCHGL - ACMPXCHGW - ACMPXCHG8B - ACPUID - AINVD - AINVLPG - ALFENCE - AMFENCE - AMOVNTIL - ARDMSR - ARDPMC - ARDTSC - ARSM - ASFENCE - ASYSRET - AWBINVD - AWRMSR - AXADDB - AXADDL - AXADDW - - // conditional move - ACMOVLCC - ACMOVLCS - ACMOVLEQ - ACMOVLGE - ACMOVLGT - ACMOVLHI - ACMOVLLE - ACMOVLLS - ACMOVLLT - ACMOVLMI - ACMOVLNE - ACMOVLOC - ACMOVLOS - ACMOVLPC - ACMOVLPL - ACMOVLPS - ACMOVQCC - ACMOVQCS - ACMOVQEQ - ACMOVQGE - ACMOVQGT - ACMOVQHI - ACMOVQLE - ACMOVQLS - ACMOVQLT - ACMOVQMI - ACMOVQNE - ACMOVQOC - ACMOVQOS - ACMOVQPC - ACMOVQPL - ACMOVQPS - ACMOVWCC - ACMOVWCS - ACMOVWEQ - ACMOVWGE - ACMOVWGT - ACMOVWHI - ACMOVWLE - ACMOVWLS - ACMOVWLT - ACMOVWMI - ACMOVWNE - ACMOVWOC - ACMOVWOS - ACMOVWPC - ACMOVWPL - ACMOVWPS - - // 64-bit - AADCQ - AADDQ - AANDQ - ABSFQ - ABSRQ - ABTCQ - ABTQ - ABTRQ - ABTSQ - ACMPQ - ACMPSQ - ACMPXCHGQ - ACQO - ADIVQ - AIDIVQ - AIMULQ - AIRETQ - AJCXZQ - ALEAQ - ALEAVEQ - ALODSQ - AMOVQ - AMOVLQSX - AMOVLQZX - AMOVNTIQ - AMOVSQ - AMULQ - ANEGQ - ANOTQ - AORQ - APOPFQ - APOPQ - APUSHFQ - APUSHQ - ARCLQ - ARCRQ - AROLQ - ARORQ - AQUAD - ASALQ - ASARQ - ASBBQ - ASCASQ - ASHLQ - ASHRQ - ASTOSQ - ASUBQ - ATESTQ - AXADDQ - AXCHGQ - AXORQ - AXGETBV - - // media - AADDPD - AADDPS - AADDSD - AADDSS - AANDNL - AANDNQ - AANDNPD - AANDNPS - AANDPD - AANDPS - ABEXTRL - ABEXTRQ - ABLSIL - ABLSIQ - ABLSMSKL - ABLSMSKQ - ABLSRL - ABLSRQ - ABZHIL - ABZHIQ - ACMPPD - ACMPPS - ACMPSD - ACMPSS - ACOMISD - ACOMISS - ACVTPD2PL - ACVTPD2PS - ACVTPL2PD - ACVTPL2PS - ACVTPS2PD - ACVTPS2PL - ACVTSD2SL - ACVTSD2SQ - ACVTSD2SS - ACVTSL2SD - ACVTSL2SS - ACVTSQ2SD - ACVTSQ2SS - ACVTSS2SD - ACVTSS2SL - ACVTSS2SQ - ACVTTPD2PL - ACVTTPS2PL - ACVTTSD2SL - ACVTTSD2SQ - ACVTTSS2SL - ACVTTSS2SQ - ADIVPD - ADIVPS - ADIVSD - ADIVSS - AEMMS - AFXRSTOR - AFXRSTOR64 - AFXSAVE - AFXSAVE64 - ALDDQU - ALDMXCSR - AMASKMOVOU - AMASKMOVQ - AMAXPD - AMAXPS - AMAXSD - AMAXSS - AMINPD - AMINPS - AMINSD - AMINSS - AMOVAPD - AMOVAPS - AMOVOU - AMOVHLPS - AMOVHPD - AMOVHPS - AMOVLHPS - AMOVLPD - AMOVLPS - AMOVMSKPD - AMOVMSKPS - AMOVNTO - AMOVNTPD - AMOVNTPS - AMOVNTQ - AMOVO - AMOVQOZX - AMOVSD - AMOVSS - AMOVUPD - AMOVUPS - AMULPD - AMULPS - AMULSD - AMULSS - AMULXL - AMULXQ - AORPD - AORPS - APACKSSLW - APACKSSWB - APACKUSWB - APADDB - APADDL - APADDQ - APADDSB - APADDSW - APADDUSB - APADDUSW - APADDW - APAND - APANDN - APAVGB - APAVGW - APCMPEQB - APCMPEQL - APCMPEQW - APCMPGTB - APCMPGTL - APCMPGTW - APDEPL - APDEPQ - APEXTL - APEXTQ - APEXTRB - APEXTRD - APEXTRQ - APEXTRW - APHADDD - APHADDSW - APHADDW - APHMINPOSUW - APHSUBD - APHSUBSW - APHSUBW - APINSRB - APINSRD - APINSRQ - APINSRW - APMADDWL - APMAXSW - APMAXUB - APMINSW - APMINUB - APMOVMSKB - APMOVSXBD - APMOVSXBQ - APMOVSXBW - APMOVSXDQ - APMOVSXWD - APMOVSXWQ - APMOVZXBD - APMOVZXBQ - APMOVZXBW - APMOVZXDQ - APMOVZXWD - APMOVZXWQ - APMULDQ - APMULHUW - APMULHW - APMULLD - APMULLW - APMULULQ - APOR - APSADBW - APSHUFB - APSHUFHW - APSHUFL - APSHUFLW - APSHUFW - APSLLL - APSLLO - APSLLQ - APSLLW - APSRAL - APSRAW - APSRLL - APSRLO - APSRLQ - APSRLW - APSUBB - APSUBL - APSUBQ - APSUBSB - APSUBSW - APSUBUSB - APSUBUSW - APSUBW - APUNPCKHBW - APUNPCKHLQ - APUNPCKHQDQ - APUNPCKHWL - APUNPCKLBW - APUNPCKLLQ - APUNPCKLQDQ - APUNPCKLWL - APXOR - ARCPPS - ARCPSS - ARSQRTPS - ARSQRTSS - ASARXL - ASARXQ - ASHLXL - ASHLXQ - ASHRXL - ASHRXQ - ASHUFPD - ASHUFPS - ASQRTPD - ASQRTPS - ASQRTSD - ASQRTSS - ASTMXCSR - ASUBPD - ASUBPS - ASUBSD - ASUBSS - AUCOMISD - AUCOMISS - AUNPCKHPD - AUNPCKHPS - AUNPCKLPD - AUNPCKLPS - AXORPD - AXORPS - APCMPESTRI - - ARETFW - ARETFL - ARETFQ - ASWAPGS - - AMODE - ACRC32B - ACRC32Q - AIMUL3Q - - APREFETCHT0 - APREFETCHT1 - APREFETCHT2 - APREFETCHNTA - - AMOVQL - ABSWAPL - ABSWAPQ - - AAESENC - AAESENCLAST - AAESDEC - AAESDECLAST - AAESIMC - AAESKEYGENASSIST - - AROUNDPS - AROUNDSS - AROUNDPD - AROUNDSD - AMOVDDUP - AMOVSHDUP - AMOVSLDUP - - APSHUFD - APCLMULQDQ - - AVZEROUPPER - AVMOVDQU - AVMOVNTDQ - AVMOVDQA - AVPCMPEQB - AVPXOR - AVPMOVMSKB - AVPAND - AVPTEST - AVPBROADCASTB - AVPSHUFB - AVPSHUFD - AVPERM2F128 - AVPALIGNR - AVPADDQ - AVPADDD - AVPSRLDQ - AVPSLLDQ - AVPSRLQ - AVPSLLQ - AVPSRLD - AVPSLLD - AVPOR - AVPBLENDD - AVINSERTI128 - AVPERM2I128 - ARORXL - ARORXQ - AVBROADCASTSS - AVBROADCASTSD - AVMOVDDUP - AVMOVSHDUP - AVMOVSLDUP - - // from 386 - AJCXZW - AFCMOVCC - AFCMOVCS - AFCMOVEQ - AFCMOVHI - AFCMOVLS - AFCMOVNE - AFCMOVNU - AFCMOVUN - AFCOMI - AFCOMIP - AFUCOMI - AFUCOMIP - - // TSX - AXACQUIRE - AXRELEASE - AXBEGIN - AXEND - AXABORT - AXTEST - - ALAST -) - -const ( - REG_NONE = 0 -) - -const ( - REG_AL = obj.RBaseAMD64 + iota - REG_CL - REG_DL - REG_BL - REG_SPB - REG_BPB - REG_SIB - REG_DIB - REG_R8B - REG_R9B - REG_R10B - REG_R11B - REG_R12B - REG_R13B - REG_R14B - REG_R15B - - REG_AX - REG_CX - REG_DX - REG_BX - REG_SP - REG_BP - REG_SI - REG_DI - REG_R8 - REG_R9 - REG_R10 - REG_R11 - REG_R12 - REG_R13 - REG_R14 - REG_R15 - - REG_AH - REG_CH - REG_DH - REG_BH - - REG_F0 - REG_F1 - REG_F2 - REG_F3 - REG_F4 - REG_F5 - REG_F6 - REG_F7 - - REG_M0 - REG_M1 - REG_M2 - REG_M3 - REG_M4 - REG_M5 - REG_M6 - REG_M7 - - REG_X0 - REG_X1 - REG_X2 - REG_X3 - REG_X4 - REG_X5 - REG_X6 - REG_X7 - REG_X8 - REG_X9 - REG_X10 - REG_X11 - REG_X12 - REG_X13 - REG_X14 - REG_X15 - - REG_Y0 - REG_Y1 - REG_Y2 - REG_Y3 - REG_Y4 - REG_Y5 - REG_Y6 - REG_Y7 - REG_Y8 - REG_Y9 - REG_Y10 - REG_Y11 - REG_Y12 - REG_Y13 - REG_Y14 - REG_Y15 - - REG_CS - REG_SS - REG_DS - REG_ES - REG_FS - REG_GS - - REG_GDTR /* global descriptor table register */ - REG_IDTR /* interrupt descriptor table register */ - REG_LDTR /* local descriptor table register */ - REG_MSW /* machine status word */ - REG_TASK /* task register */ - - REG_CR0 - REG_CR1 - REG_CR2 - REG_CR3 - REG_CR4 - REG_CR5 - REG_CR6 - REG_CR7 - REG_CR8 - REG_CR9 - REG_CR10 - REG_CR11 - REG_CR12 - REG_CR13 - REG_CR14 - REG_CR15 - - REG_DR0 - REG_DR1 - REG_DR2 - REG_DR3 - REG_DR4 - REG_DR5 - REG_DR6 - REG_DR7 - - REG_TR0 - REG_TR1 - REG_TR2 - REG_TR3 - REG_TR4 - REG_TR5 - REG_TR6 - REG_TR7 - - REG_TLS - - MAXREG - - REG_CR = REG_CR0 - REG_DR = REG_DR0 - REG_TR = REG_TR0 - - REGARG = -1 - REGRET = REG_AX - FREGRET = REG_X0 - REGSP = REG_SP - REGCTXT = REG_DX - REGEXT = REG_R15 /* compiler allocates external registers R15 down */ - FREGMIN = REG_X0 + 5 /* first register variable */ - FREGEXT = REG_X0 + 15 /* first external register */ - T_TYPE = 1 << 0 - T_INDEX = 1 << 1 - T_OFFSET = 1 << 2 - T_FCONST = 1 << 3 - T_SYM = 1 << 4 - T_SCONST = 1 << 5 - T_64 = 1 << 6 - T_GOTYPE = 1 << 7 -) diff --git a/vendor/github.com/google/gops/internal/obj/x86/anames.go b/vendor/github.com/google/gops/internal/obj/x86/anames.go deleted file mode 100644 index 5f5e8b8b..00000000 --- a/vendor/github.com/google/gops/internal/obj/x86/anames.go +++ /dev/null @@ -1,769 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p x86 -// Do not edit. - -package x86 - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "AAA", - "AAD", - "AAM", - "AAS", - "ADCB", - "ADCL", - "ADCW", - "ADDB", - "ADDL", - "ADDW", - "ADJSP", - "ANDB", - "ANDL", - "ANDW", - "ARPL", - "BOUNDL", - "BOUNDW", - "BSFL", - "BSFW", - "BSRL", - "BSRW", - "BTL", - "BTW", - "BTCL", - "BTCW", - "BTRL", - "BTRW", - "BTSL", - "BTSW", - "BYTE", - "CLC", - "CLD", - "CLI", - "CLTS", - "CMC", - "CMPB", - "CMPL", - "CMPW", - "CMPSB", - "CMPSL", - "CMPSW", - "DAA", - "DAS", - "DECB", - "DECL", - "DECQ", - "DECW", - "DIVB", - "DIVL", - "DIVW", - "ENTER", - "HADDPD", - "HADDPS", - "HLT", - "HSUBPD", - "HSUBPS", - "IDIVB", - "IDIVL", - "IDIVW", - "IMULB", - "IMULL", - "IMULW", - "INB", - "INL", - "INW", - "INCB", - "INCL", - "INCQ", - "INCW", - "INSB", - "INSL", - "INSW", - "INT", - "INTO", - "IRETL", - "IRETW", - "JCC", - "JCS", - "JCXZL", - "JEQ", - "JGE", - "JGT", - "JHI", - "JLE", - "JLS", - "JLT", - "JMI", - "JNE", - "JOC", - "JOS", - "JPC", - "JPL", - "JPS", - "LAHF", - "LARL", - "LARW", - "LEAL", - "LEAW", - "LEAVEL", - "LEAVEW", - "LOCK", - "LODSB", - "LODSL", - "LODSW", - "LONG", - "LOOP", - "LOOPEQ", - "LOOPNE", - "LSLL", - "LSLW", - "MOVB", - "MOVL", - "MOVW", - "MOVBLSX", - "MOVBLZX", - "MOVBQSX", - "MOVBQZX", - "MOVBWSX", - "MOVBWZX", - "MOVWLSX", - "MOVWLZX", - "MOVWQSX", - "MOVWQZX", - "MOVSB", - "MOVSL", - "MOVSW", - "MULB", - "MULL", - "MULW", - "NEGB", - "NEGL", - "NEGW", - "NOTB", - "NOTL", - "NOTW", - "ORB", - "ORL", - "ORW", - "OUTB", - "OUTL", - "OUTW", - "OUTSB", - "OUTSL", - "OUTSW", - "PAUSE", - "POPAL", - "POPAW", - "POPCNTW", - "POPCNTL", - "POPCNTQ", - "POPFL", - "POPFW", - "POPL", - "POPW", - "PUSHAL", - "PUSHAW", - "PUSHFL", - "PUSHFW", - "PUSHL", - "PUSHW", - "RCLB", - "RCLL", - "RCLW", - "RCRB", - "RCRL", - "RCRW", - "REP", - "REPN", - "ROLB", - "ROLL", - "ROLW", - "RORB", - "RORL", - "RORW", - "SAHF", - "SALB", - "SALL", - "SALW", - "SARB", - "SARL", - "SARW", - "SBBB", - "SBBL", - "SBBW", - "SCASB", - "SCASL", - "SCASW", - "SETCC", - "SETCS", - "SETEQ", - "SETGE", - "SETGT", - "SETHI", - "SETLE", - "SETLS", - "SETLT", - "SETMI", - "SETNE", - "SETOC", - "SETOS", - "SETPC", - "SETPL", - "SETPS", - "CDQ", - "CWD", - "SHLB", - "SHLL", - "SHLW", - "SHRB", - "SHRL", - "SHRW", - "STC", - "STD", - "STI", - "STOSB", - "STOSL", - "STOSW", - "SUBB", - "SUBL", - "SUBW", - "SYSCALL", - "TESTB", - "TESTL", - "TESTW", - "VERR", - "VERW", - "WAIT", - "WORD", - "XCHGB", - "XCHGL", - "XCHGW", - "XLAT", - "XORB", - "XORL", - "XORW", - "FMOVB", - "FMOVBP", - "FMOVD", - "FMOVDP", - "FMOVF", - "FMOVFP", - "FMOVL", - "FMOVLP", - "FMOVV", - "FMOVVP", - "FMOVW", - "FMOVWP", - "FMOVX", - "FMOVXP", - "FCOMD", - "FCOMDP", - "FCOMDPP", - "FCOMF", - "FCOMFP", - "FCOML", - "FCOMLP", - "FCOMW", - "FCOMWP", - "FUCOM", - "FUCOMP", - "FUCOMPP", - "FADDDP", - "FADDW", - "FADDL", - "FADDF", - "FADDD", - "FMULDP", - "FMULW", - "FMULL", - "FMULF", - "FMULD", - "FSUBDP", - "FSUBW", - "FSUBL", - "FSUBF", - "FSUBD", - "FSUBRDP", - "FSUBRW", - "FSUBRL", - "FSUBRF", - "FSUBRD", - "FDIVDP", - "FDIVW", - "FDIVL", - "FDIVF", - "FDIVD", - "FDIVRDP", - "FDIVRW", - "FDIVRL", - "FDIVRF", - "FDIVRD", - "FXCHD", - "FFREE", - "FLDCW", - "FLDENV", - "FRSTOR", - "FSAVE", - "FSTCW", - "FSTENV", - "FSTSW", - "F2XM1", - "FABS", - "FCHS", - "FCLEX", - "FCOS", - "FDECSTP", - "FINCSTP", - "FINIT", - "FLD1", - "FLDL2E", - "FLDL2T", - "FLDLG2", - "FLDLN2", - "FLDPI", - "FLDZ", - "FNOP", - "FPATAN", - "FPREM", - "FPREM1", - "FPTAN", - "FRNDINT", - "FSCALE", - "FSIN", - "FSINCOS", - "FSQRT", - "FTST", - "FXAM", - "FXTRACT", - "FYL2X", - "FYL2XP1", - "CMPXCHGB", - "CMPXCHGL", - "CMPXCHGW", - "CMPXCHG8B", - "CPUID", - "INVD", - "INVLPG", - "LFENCE", - "MFENCE", - "MOVNTIL", - "RDMSR", - "RDPMC", - "RDTSC", - "RSM", - "SFENCE", - "SYSRET", - "WBINVD", - "WRMSR", - "XADDB", - "XADDL", - "XADDW", - "CMOVLCC", - "CMOVLCS", - "CMOVLEQ", - "CMOVLGE", - "CMOVLGT", - "CMOVLHI", - "CMOVLLE", - "CMOVLLS", - "CMOVLLT", - "CMOVLMI", - "CMOVLNE", - "CMOVLOC", - "CMOVLOS", - "CMOVLPC", - "CMOVLPL", - "CMOVLPS", - "CMOVQCC", - "CMOVQCS", - "CMOVQEQ", - "CMOVQGE", - "CMOVQGT", - "CMOVQHI", - "CMOVQLE", - "CMOVQLS", - "CMOVQLT", - "CMOVQMI", - "CMOVQNE", - "CMOVQOC", - "CMOVQOS", - "CMOVQPC", - "CMOVQPL", - "CMOVQPS", - "CMOVWCC", - "CMOVWCS", - "CMOVWEQ", - "CMOVWGE", - "CMOVWGT", - "CMOVWHI", - "CMOVWLE", - "CMOVWLS", - "CMOVWLT", - "CMOVWMI", - "CMOVWNE", - "CMOVWOC", - "CMOVWOS", - "CMOVWPC", - "CMOVWPL", - "CMOVWPS", - "ADCQ", - "ADDQ", - "ANDQ", - "BSFQ", - "BSRQ", - "BTCQ", - "BTQ", - "BTRQ", - "BTSQ", - "CMPQ", - "CMPSQ", - "CMPXCHGQ", - "CQO", - "DIVQ", - "IDIVQ", - "IMULQ", - "IRETQ", - "JCXZQ", - "LEAQ", - "LEAVEQ", - "LODSQ", - "MOVQ", - "MOVLQSX", - "MOVLQZX", - "MOVNTIQ", - "MOVSQ", - "MULQ", - "NEGQ", - "NOTQ", - "ORQ", - "POPFQ", - "POPQ", - "PUSHFQ", - "PUSHQ", - "RCLQ", - "RCRQ", - "ROLQ", - "RORQ", - "QUAD", - "SALQ", - "SARQ", - "SBBQ", - "SCASQ", - "SHLQ", - "SHRQ", - "STOSQ", - "SUBQ", - "TESTQ", - "XADDQ", - "XCHGQ", - "XORQ", - "XGETBV", - "ADDPD", - "ADDPS", - "ADDSD", - "ADDSS", - "ANDNL", - "ANDNQ", - "ANDNPD", - "ANDNPS", - "ANDPD", - "ANDPS", - "BEXTRL", - "BEXTRQ", - "BLSIL", - "BLSIQ", - "BLSMSKL", - "BLSMSKQ", - "BLSRL", - "BLSRQ", - "BZHIL", - "BZHIQ", - "CMPPD", - "CMPPS", - "CMPSD", - "CMPSS", - "COMISD", - "COMISS", - "CVTPD2PL", - "CVTPD2PS", - "CVTPL2PD", - "CVTPL2PS", - "CVTPS2PD", - "CVTPS2PL", - "CVTSD2SL", - "CVTSD2SQ", - "CVTSD2SS", - "CVTSL2SD", - "CVTSL2SS", - "CVTSQ2SD", - "CVTSQ2SS", - "CVTSS2SD", - "CVTSS2SL", - "CVTSS2SQ", - "CVTTPD2PL", - "CVTTPS2PL", - "CVTTSD2SL", - "CVTTSD2SQ", - "CVTTSS2SL", - "CVTTSS2SQ", - "DIVPD", - "DIVPS", - "DIVSD", - "DIVSS", - "EMMS", - "FXRSTOR", - "FXRSTOR64", - "FXSAVE", - "FXSAVE64", - "LDDQU", - "LDMXCSR", - "MASKMOVOU", - "MASKMOVQ", - "MAXPD", - "MAXPS", - "MAXSD", - "MAXSS", - "MINPD", - "MINPS", - "MINSD", - "MINSS", - "MOVAPD", - "MOVAPS", - "MOVOU", - "MOVHLPS", - "MOVHPD", - "MOVHPS", - "MOVLHPS", - "MOVLPD", - "MOVLPS", - "MOVMSKPD", - "MOVMSKPS", - "MOVNTO", - "MOVNTPD", - "MOVNTPS", - "MOVNTQ", - "MOVO", - "MOVQOZX", - "MOVSD", - "MOVSS", - "MOVUPD", - "MOVUPS", - "MULPD", - "MULPS", - "MULSD", - "MULSS", - "MULXL", - "MULXQ", - "ORPD", - "ORPS", - "PACKSSLW", - "PACKSSWB", - "PACKUSWB", - "PADDB", - "PADDL", - "PADDQ", - "PADDSB", - "PADDSW", - "PADDUSB", - "PADDUSW", - "PADDW", - "PAND", - "PANDN", - "PAVGB", - "PAVGW", - "PCMPEQB", - "PCMPEQL", - "PCMPEQW", - "PCMPGTB", - "PCMPGTL", - "PCMPGTW", - "PDEPL", - "PDEPQ", - "PEXTL", - "PEXTQ", - "PEXTRB", - "PEXTRD", - "PEXTRQ", - "PEXTRW", - "PHADDD", - "PHADDSW", - "PHADDW", - "PHMINPOSUW", - "PHSUBD", - "PHSUBSW", - "PHSUBW", - "PINSRB", - "PINSRD", - "PINSRQ", - "PINSRW", - "PMADDWL", - "PMAXSW", - "PMAXUB", - "PMINSW", - "PMINUB", - "PMOVMSKB", - "PMOVSXBD", - "PMOVSXBQ", - "PMOVSXBW", - "PMOVSXDQ", - "PMOVSXWD", - "PMOVSXWQ", - "PMOVZXBD", - "PMOVZXBQ", - "PMOVZXBW", - "PMOVZXDQ", - "PMOVZXWD", - "PMOVZXWQ", - "PMULDQ", - "PMULHUW", - "PMULHW", - "PMULLD", - "PMULLW", - "PMULULQ", - "POR", - "PSADBW", - "PSHUFB", - "PSHUFHW", - "PSHUFL", - "PSHUFLW", - "PSHUFW", - "PSLLL", - "PSLLO", - "PSLLQ", - "PSLLW", - "PSRAL", - "PSRAW", - "PSRLL", - "PSRLO", - "PSRLQ", - "PSRLW", - "PSUBB", - "PSUBL", - "PSUBQ", - "PSUBSB", - "PSUBSW", - "PSUBUSB", - "PSUBUSW", - "PSUBW", - "PUNPCKHBW", - "PUNPCKHLQ", - "PUNPCKHQDQ", - "PUNPCKHWL", - "PUNPCKLBW", - "PUNPCKLLQ", - "PUNPCKLQDQ", - "PUNPCKLWL", - "PXOR", - "RCPPS", - "RCPSS", - "RSQRTPS", - "RSQRTSS", - "SARXL", - "SARXQ", - "SHLXL", - "SHLXQ", - "SHRXL", - "SHRXQ", - "SHUFPD", - "SHUFPS", - "SQRTPD", - "SQRTPS", - "SQRTSD", - "SQRTSS", - "STMXCSR", - "SUBPD", - "SUBPS", - "SUBSD", - "SUBSS", - "UCOMISD", - "UCOMISS", - "UNPCKHPD", - "UNPCKHPS", - "UNPCKLPD", - "UNPCKLPS", - "XORPD", - "XORPS", - "PCMPESTRI", - "RETFW", - "RETFL", - "RETFQ", - "SWAPGS", - "MODE", - "CRC32B", - "CRC32Q", - "IMUL3Q", - "PREFETCHT0", - "PREFETCHT1", - "PREFETCHT2", - "PREFETCHNTA", - "MOVQL", - "BSWAPL", - "BSWAPQ", - "AESENC", - "AESENCLAST", - "AESDEC", - "AESDECLAST", - "AESIMC", - "AESKEYGENASSIST", - "ROUNDPS", - "ROUNDSS", - "ROUNDPD", - "ROUNDSD", - "MOVDDUP", - "MOVSHDUP", - "MOVSLDUP", - "PSHUFD", - "PCLMULQDQ", - "VZEROUPPER", - "VMOVDQU", - "VMOVNTDQ", - "VMOVDQA", - "VPCMPEQB", - "VPXOR", - "VPMOVMSKB", - "VPAND", - "VPTEST", - "VPBROADCASTB", - "VPSHUFB", - "VPSHUFD", - "VPERM2F128", - "VPALIGNR", - "VPADDQ", - "VPADDD", - "VPSRLDQ", - "VPSLLDQ", - "VPSRLQ", - "VPSLLQ", - "VPSRLD", - "VPSLLD", - "VPOR", - "VPBLENDD", - "VINSERTI128", - "VPERM2I128", - "RORXL", - "RORXQ", - "VBROADCASTSS", - "VBROADCASTSD", - "VMOVDDUP", - "VMOVSHDUP", - "VMOVSLDUP", - "JCXZW", - "FCMOVCC", - "FCMOVCS", - "FCMOVEQ", - "FCMOVHI", - "FCMOVLS", - "FCMOVNE", - "FCMOVNU", - "FCMOVUN", - "FCOMI", - "FCOMIP", - "FUCOMI", - "FUCOMIP", - "XACQUIRE", - "XRELEASE", - "XBEGIN", - "XEND", - "XABORT", - "XTEST", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/x86/asm6.go b/vendor/github.com/google/gops/internal/obj/x86/asm6.go deleted file mode 100644 index d5462b8a..00000000 --- a/vendor/github.com/google/gops/internal/obj/x86/asm6.go +++ /dev/null @@ -1,4536 +0,0 @@ -// Inferno utils/6l/span.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package x86 - -import ( - "encoding/binary" - "fmt" - "log" - "strings" - - "github.com/google/gops/internal/obj" -) - -// Instruction layout. - -const ( - // Loop alignment constants: - // want to align loop entry to LoopAlign-byte boundary, - // and willing to insert at most MaxLoopPad bytes of NOP to do so. - // We define a loop entry as the target of a backward jump. - // - // gcc uses MaxLoopPad = 10 for its 'generic x86-64' config, - // and it aligns all jump targets, not just backward jump targets. - // - // As of 6/1/2012, the effect of setting MaxLoopPad = 10 here - // is very slight but negative, so the alignment is disabled by - // setting MaxLoopPad = 0. The code is here for reference and - // for future experiments. - // - LoopAlign = 16 - MaxLoopPad = 0 - funcAlign = 16 -) - -type Optab struct { - as obj.As - ytab []ytab - prefix uint8 - op [23]uint8 -} - -type ytab struct { - from uint8 - from3 uint8 - to uint8 - zcase uint8 - zoffset uint8 -} - -type Movtab struct { - as obj.As - ft uint8 - f3t uint8 - tt uint8 - code uint8 - op [4]uint8 -} - -const ( - Yxxx = iota - Ynone - Yi0 // $0 - Yi1 // $1 - Yi8 // $x, x fits in int8 - Yu8 // $x, x fits in uint8 - Yu7 // $x, x in 0..127 (fits in both int8 and uint8) - Ys32 - Yi32 - Yi64 - Yiauto - Yal - Ycl - Yax - Ycx - Yrb - Yrl - Yrl32 // Yrl on 32-bit system - Yrf - Yf0 - Yrx - Ymb - Yml - Ym - Ybr - Ycs - Yss - Yds - Yes - Yfs - Ygs - Ygdtr - Yidtr - Yldtr - Ymsw - Ytask - Ycr0 - Ycr1 - Ycr2 - Ycr3 - Ycr4 - Ycr5 - Ycr6 - Ycr7 - Ycr8 - Ydr0 - Ydr1 - Ydr2 - Ydr3 - Ydr4 - Ydr5 - Ydr6 - Ydr7 - Ytr0 - Ytr1 - Ytr2 - Ytr3 - Ytr4 - Ytr5 - Ytr6 - Ytr7 - Ymr - Ymm - Yxr - Yxm - Yyr - Yym - Ytls - Ytextsize - Yindir - Ymax -) - -const ( - Zxxx = iota - Zlit - Zlitm_r - Z_rp - Zbr - Zcall - Zcallcon - Zcallduff - Zcallind - Zcallindreg - Zib_ - Zib_rp - Zibo_m - Zibo_m_xm - Zil_ - Zil_rp - Ziq_rp - Zilo_m - Zjmp - Zjmpcon - Zloop - Zo_iw - Zm_o - Zm_r - Zm2_r - Zm_r_xm - Zm_r_i_xm - Zm_r_xm_nr - Zr_m_xm_nr - Zibm_r /* mmx1,mmx2/mem64,imm8 */ - Zibr_m - Zmb_r - Zaut_r - Zo_m - Zo_m64 - Zpseudo - Zr_m - Zr_m_xm - Zrp_ - Z_ib - Z_il - Zm_ibo - Zm_ilo - Zib_rr - Zil_rr - Zclr - Zbyte - Zvex_rm_v_r - Zvex_r_v_rm - Zvex_v_rm_r - Zvex_i_rm_r - Zvex_i_r_v - Zvex_i_rm_v_r - Zmax -) - -const ( - Px = 0 - Px1 = 1 // symbolic; exact value doesn't matter - P32 = 0x32 /* 32-bit only */ - Pe = 0x66 /* operand escape */ - Pm = 0x0f /* 2byte opcode escape */ - Pq = 0xff /* both escapes: 66 0f */ - Pb = 0xfe /* byte operands */ - Pf2 = 0xf2 /* xmm escape 1: f2 0f */ - Pf3 = 0xf3 /* xmm escape 2: f3 0f */ - Pef3 = 0xf5 /* xmm escape 2 with 16-bit prefix: 66 f3 0f */ - Pq3 = 0x67 /* xmm escape 3: 66 48 0f */ - Pq4 = 0x68 /* xmm escape 4: 66 0F 38 */ - Pfw = 0xf4 /* Pf3 with Rex.w: f3 48 0f */ - Pw = 0x48 /* Rex.w */ - Pw8 = 0x90 // symbolic; exact value doesn't matter - Py = 0x80 /* defaults to 64-bit mode */ - Py1 = 0x81 // symbolic; exact value doesn't matter - Py3 = 0x83 // symbolic; exact value doesn't matter - Pvex = 0x84 // symbolic: exact value doesn't matter - - Rxw = 1 << 3 /* =1, 64-bit operand size */ - Rxr = 1 << 2 /* extend modrm reg */ - Rxx = 1 << 1 /* extend sib index */ - Rxb = 1 << 0 /* extend modrm r/m, sib base, or opcode reg */ -) - -const ( - // Encoding for VEX prefix in tables. - // The P, L, and W fields are chosen to match - // their eventual locations in the VEX prefix bytes. - - // P field - 2 bits - vex66 = 1 << 0 - vexF3 = 2 << 0 - vexF2 = 3 << 0 - // L field - 1 bit - vexLZ = 0 << 2 - vexLIG = 0 << 2 - vex128 = 0 << 2 - vex256 = 1 << 2 - // W field - 1 bit - vexWIG = 0 << 7 - vexW0 = 0 << 7 - vexW1 = 1 << 7 - // M field - 5 bits, but mostly reserved; we can store up to 4 - vex0F = 1 << 3 - vex0F38 = 2 << 3 - vex0F3A = 3 << 3 - - // Combinations used in the manual. - VEX_128_0F_WIG = vex128 | vex0F | vexWIG - VEX_128_66_0F_W0 = vex128 | vex66 | vex0F | vexW0 - VEX_128_66_0F_W1 = vex128 | vex66 | vex0F | vexW1 - VEX_128_66_0F_WIG = vex128 | vex66 | vex0F | vexWIG - VEX_128_66_0F38_W0 = vex128 | vex66 | vex0F38 | vexW0 - VEX_128_66_0F38_W1 = vex128 | vex66 | vex0F38 | vexW1 - VEX_128_66_0F38_WIG = vex128 | vex66 | vex0F38 | vexWIG - VEX_128_66_0F3A_W0 = vex128 | vex66 | vex0F3A | vexW0 - VEX_128_66_0F3A_W1 = vex128 | vex66 | vex0F3A | vexW1 - VEX_128_66_0F3A_WIG = vex128 | vex66 | vex0F3A | vexWIG - VEX_128_F2_0F_WIG = vex128 | vexF2 | vex0F | vexWIG - VEX_128_F3_0F_WIG = vex128 | vexF3 | vex0F | vexWIG - VEX_256_66_0F_WIG = vex256 | vex66 | vex0F | vexWIG - VEX_256_66_0F38_W0 = vex256 | vex66 | vex0F38 | vexW0 - VEX_256_66_0F38_W1 = vex256 | vex66 | vex0F38 | vexW1 - VEX_256_66_0F38_WIG = vex256 | vex66 | vex0F38 | vexWIG - VEX_256_66_0F3A_W0 = vex256 | vex66 | vex0F3A | vexW0 - VEX_256_66_0F3A_W1 = vex256 | vex66 | vex0F3A | vexW1 - VEX_256_66_0F3A_WIG = vex256 | vex66 | vex0F3A | vexWIG - VEX_256_F2_0F_WIG = vex256 | vexF2 | vex0F | vexWIG - VEX_256_F3_0F_WIG = vex256 | vexF3 | vex0F | vexWIG - VEX_LIG_0F_WIG = vexLIG | vex0F | vexWIG - VEX_LIG_66_0F_WIG = vexLIG | vex66 | vex0F | vexWIG - VEX_LIG_66_0F38_W0 = vexLIG | vex66 | vex0F38 | vexW0 - VEX_LIG_66_0F38_W1 = vexLIG | vex66 | vex0F38 | vexW1 - VEX_LIG_66_0F3A_WIG = vexLIG | vex66 | vex0F3A | vexWIG - VEX_LIG_F2_0F_W0 = vexLIG | vexF2 | vex0F | vexW0 - VEX_LIG_F2_0F_W1 = vexLIG | vexF2 | vex0F | vexW1 - VEX_LIG_F2_0F_WIG = vexLIG | vexF2 | vex0F | vexWIG - VEX_LIG_F3_0F_W0 = vexLIG | vexF3 | vex0F | vexW0 - VEX_LIG_F3_0F_W1 = vexLIG | vexF3 | vex0F | vexW1 - VEX_LIG_F3_0F_WIG = vexLIG | vexF3 | vex0F | vexWIG - VEX_LZ_0F_WIG = vexLZ | vex0F | vexWIG - VEX_LZ_0F38_W0 = vexLZ | vex0F38 | vexW0 - VEX_LZ_0F38_W1 = vexLZ | vex0F38 | vexW1 - VEX_LZ_66_0F38_W0 = vexLZ | vex66 | vex0F38 | vexW0 - VEX_LZ_66_0F38_W1 = vexLZ | vex66 | vex0F38 | vexW1 - VEX_LZ_F2_0F38_W0 = vexLZ | vexF2 | vex0F38 | vexW0 - VEX_LZ_F2_0F38_W1 = vexLZ | vexF2 | vex0F38 | vexW1 - VEX_LZ_F2_0F3A_W0 = vexLZ | vexF2 | vex0F3A | vexW0 - VEX_LZ_F2_0F3A_W1 = vexLZ | vexF2 | vex0F3A | vexW1 - VEX_LZ_F3_0F38_W0 = vexLZ | vexF3 | vex0F38 | vexW0 - VEX_LZ_F3_0F38_W1 = vexLZ | vexF3 | vex0F38 | vexW1 -) - -var ycover [Ymax * Ymax]uint8 - -var reg [MAXREG]int - -var regrex [MAXREG + 1]int - -var ynone = []ytab{ - {Ynone, Ynone, Ynone, Zlit, 1}, -} - -var ytext = []ytab{ - {Ymb, Ynone, Ytextsize, Zpseudo, 0}, - {Ymb, Yi32, Ytextsize, Zpseudo, 1}, -} - -var ynop = []ytab{ - {Ynone, Ynone, Ynone, Zpseudo, 0}, - {Ynone, Ynone, Yiauto, Zpseudo, 0}, - {Ynone, Ynone, Yml, Zpseudo, 0}, - {Ynone, Ynone, Yrf, Zpseudo, 0}, - {Ynone, Ynone, Yxr, Zpseudo, 0}, - {Yiauto, Ynone, Ynone, Zpseudo, 0}, - {Yml, Ynone, Ynone, Zpseudo, 0}, - {Yrf, Ynone, Ynone, Zpseudo, 0}, - {Yxr, Ynone, Ynone, Zpseudo, 1}, -} - -var yfuncdata = []ytab{ - {Yi32, Ynone, Ym, Zpseudo, 0}, -} - -var ypcdata = []ytab{ - {Yi32, Ynone, Yi32, Zpseudo, 0}, -} - -var yxorb = []ytab{ - {Yi32, Ynone, Yal, Zib_, 1}, - {Yi32, Ynone, Ymb, Zibo_m, 2}, - {Yrb, Ynone, Ymb, Zr_m, 1}, - {Ymb, Ynone, Yrb, Zm_r, 1}, -} - -var yaddl = []ytab{ - {Yi8, Ynone, Yml, Zibo_m, 2}, - {Yi32, Ynone, Yax, Zil_, 1}, - {Yi32, Ynone, Yml, Zilo_m, 2}, - {Yrl, Ynone, Yml, Zr_m, 1}, - {Yml, Ynone, Yrl, Zm_r, 1}, -} - -var yincl = []ytab{ - {Ynone, Ynone, Yrl, Z_rp, 1}, - {Ynone, Ynone, Yml, Zo_m, 2}, -} - -var yincq = []ytab{ - {Ynone, Ynone, Yml, Zo_m, 2}, -} - -var ycmpb = []ytab{ - {Yal, Ynone, Yi32, Z_ib, 1}, - {Ymb, Ynone, Yi32, Zm_ibo, 2}, - {Ymb, Ynone, Yrb, Zm_r, 1}, - {Yrb, Ynone, Ymb, Zr_m, 1}, -} - -var ycmpl = []ytab{ - {Yml, Ynone, Yi8, Zm_ibo, 2}, - {Yax, Ynone, Yi32, Z_il, 1}, - {Yml, Ynone, Yi32, Zm_ilo, 2}, - {Yml, Ynone, Yrl, Zm_r, 1}, - {Yrl, Ynone, Yml, Zr_m, 1}, -} - -var yshb = []ytab{ - {Yi1, Ynone, Ymb, Zo_m, 2}, - {Yi32, Ynone, Ymb, Zibo_m, 2}, - {Ycx, Ynone, Ymb, Zo_m, 2}, -} - -var yshl = []ytab{ - {Yi1, Ynone, Yml, Zo_m, 2}, - {Yi32, Ynone, Yml, Zibo_m, 2}, - {Ycl, Ynone, Yml, Zo_m, 2}, - {Ycx, Ynone, Yml, Zo_m, 2}, -} - -var ytestl = []ytab{ - {Yi32, Ynone, Yax, Zil_, 1}, - {Yi32, Ynone, Yml, Zilo_m, 2}, - {Yrl, Ynone, Yml, Zr_m, 1}, - {Yml, Ynone, Yrl, Zm_r, 1}, -} - -var ymovb = []ytab{ - {Yrb, Ynone, Ymb, Zr_m, 1}, - {Ymb, Ynone, Yrb, Zm_r, 1}, - {Yi32, Ynone, Yrb, Zib_rp, 1}, - {Yi32, Ynone, Ymb, Zibo_m, 2}, -} - -var ybtl = []ytab{ - {Yi8, Ynone, Yml, Zibo_m, 2}, - {Yrl, Ynone, Yml, Zr_m, 1}, -} - -var ymovw = []ytab{ - {Yrl, Ynone, Yml, Zr_m, 1}, - {Yml, Ynone, Yrl, Zm_r, 1}, - {Yi0, Ynone, Yrl, Zclr, 1}, - {Yi32, Ynone, Yrl, Zil_rp, 1}, - {Yi32, Ynone, Yml, Zilo_m, 2}, - {Yiauto, Ynone, Yrl, Zaut_r, 2}, -} - -var ymovl = []ytab{ - {Yrl, Ynone, Yml, Zr_m, 1}, - {Yml, Ynone, Yrl, Zm_r, 1}, - {Yi0, Ynone, Yrl, Zclr, 1}, - {Yi32, Ynone, Yrl, Zil_rp, 1}, - {Yi32, Ynone, Yml, Zilo_m, 2}, - {Yml, Ynone, Ymr, Zm_r_xm, 1}, // MMX MOVD - {Ymr, Ynone, Yml, Zr_m_xm, 1}, // MMX MOVD - {Yml, Ynone, Yxr, Zm_r_xm, 2}, // XMM MOVD (32 bit) - {Yxr, Ynone, Yml, Zr_m_xm, 2}, // XMM MOVD (32 bit) - {Yiauto, Ynone, Yrl, Zaut_r, 2}, -} - -var yret = []ytab{ - {Ynone, Ynone, Ynone, Zo_iw, 1}, - {Yi32, Ynone, Ynone, Zo_iw, 1}, -} - -var ymovq = []ytab{ - // valid in 32-bit mode - {Ym, Ynone, Ymr, Zm_r_xm_nr, 1}, // 0x6f MMX MOVQ (shorter encoding) - {Ymr, Ynone, Ym, Zr_m_xm_nr, 1}, // 0x7f MMX MOVQ - {Yxr, Ynone, Ymr, Zm_r_xm_nr, 2}, // Pf2, 0xd6 MOVDQ2Q - {Yxm, Ynone, Yxr, Zm_r_xm_nr, 2}, // Pf3, 0x7e MOVQ xmm1/m64 -> xmm2 - {Yxr, Ynone, Yxm, Zr_m_xm_nr, 2}, // Pe, 0xd6 MOVQ xmm1 -> xmm2/m64 - - // valid only in 64-bit mode, usually with 64-bit prefix - {Yrl, Ynone, Yml, Zr_m, 1}, // 0x89 - {Yml, Ynone, Yrl, Zm_r, 1}, // 0x8b - {Yi0, Ynone, Yrl, Zclr, 1}, // 0x31 - {Ys32, Ynone, Yrl, Zilo_m, 2}, // 32 bit signed 0xc7,(0) - {Yi64, Ynone, Yrl, Ziq_rp, 1}, // 0xb8 -- 32/64 bit immediate - {Yi32, Ynone, Yml, Zilo_m, 2}, // 0xc7,(0) - {Ymm, Ynone, Ymr, Zm_r_xm, 1}, // 0x6e MMX MOVD - {Ymr, Ynone, Ymm, Zr_m_xm, 1}, // 0x7e MMX MOVD - {Yml, Ynone, Yxr, Zm_r_xm, 2}, // Pe, 0x6e MOVD xmm load - {Yxr, Ynone, Yml, Zr_m_xm, 2}, // Pe, 0x7e MOVD xmm store - {Yiauto, Ynone, Yrl, Zaut_r, 1}, // 0 built-in LEAQ -} - -var ym_rl = []ytab{ - {Ym, Ynone, Yrl, Zm_r, 1}, -} - -var yrl_m = []ytab{ - {Yrl, Ynone, Ym, Zr_m, 1}, -} - -var ymb_rl = []ytab{ - {Ymb, Ynone, Yrl, Zmb_r, 1}, -} - -var yml_rl = []ytab{ - {Yml, Ynone, Yrl, Zm_r, 1}, -} - -var yrl_ml = []ytab{ - {Yrl, Ynone, Yml, Zr_m, 1}, -} - -var yml_mb = []ytab{ - {Yrb, Ynone, Ymb, Zr_m, 1}, - {Ymb, Ynone, Yrb, Zm_r, 1}, -} - -var yrb_mb = []ytab{ - {Yrb, Ynone, Ymb, Zr_m, 1}, -} - -var yxchg = []ytab{ - {Yax, Ynone, Yrl, Z_rp, 1}, - {Yrl, Ynone, Yax, Zrp_, 1}, - {Yrl, Ynone, Yml, Zr_m, 1}, - {Yml, Ynone, Yrl, Zm_r, 1}, -} - -var ydivl = []ytab{ - {Yml, Ynone, Ynone, Zm_o, 2}, -} - -var ydivb = []ytab{ - {Ymb, Ynone, Ynone, Zm_o, 2}, -} - -var yimul = []ytab{ - {Yml, Ynone, Ynone, Zm_o, 2}, - {Yi8, Ynone, Yrl, Zib_rr, 1}, - {Yi32, Ynone, Yrl, Zil_rr, 1}, - {Yml, Ynone, Yrl, Zm_r, 2}, -} - -var yimul3 = []ytab{ - {Yi8, Yml, Yrl, Zibm_r, 2}, -} - -var ybyte = []ytab{ - {Yi64, Ynone, Ynone, Zbyte, 1}, -} - -var yin = []ytab{ - {Yi32, Ynone, Ynone, Zib_, 1}, - {Ynone, Ynone, Ynone, Zlit, 1}, -} - -var yint = []ytab{ - {Yi32, Ynone, Ynone, Zib_, 1}, -} - -var ypushl = []ytab{ - {Yrl, Ynone, Ynone, Zrp_, 1}, - {Ym, Ynone, Ynone, Zm_o, 2}, - {Yi8, Ynone, Ynone, Zib_, 1}, - {Yi32, Ynone, Ynone, Zil_, 1}, -} - -var ypopl = []ytab{ - {Ynone, Ynone, Yrl, Z_rp, 1}, - {Ynone, Ynone, Ym, Zo_m, 2}, -} - -var ybswap = []ytab{ - {Ynone, Ynone, Yrl, Z_rp, 2}, -} - -var yscond = []ytab{ - {Ynone, Ynone, Ymb, Zo_m, 2}, -} - -var yjcond = []ytab{ - {Ynone, Ynone, Ybr, Zbr, 0}, - {Yi0, Ynone, Ybr, Zbr, 0}, - {Yi1, Ynone, Ybr, Zbr, 1}, -} - -var yloop = []ytab{ - {Ynone, Ynone, Ybr, Zloop, 1}, -} - -var ycall = []ytab{ - {Ynone, Ynone, Yml, Zcallindreg, 0}, - {Yrx, Ynone, Yrx, Zcallindreg, 2}, - {Ynone, Ynone, Yindir, Zcallind, 2}, - {Ynone, Ynone, Ybr, Zcall, 0}, - {Ynone, Ynone, Yi32, Zcallcon, 1}, -} - -var yduff = []ytab{ - {Ynone, Ynone, Yi32, Zcallduff, 1}, -} - -var yjmp = []ytab{ - {Ynone, Ynone, Yml, Zo_m64, 2}, - {Ynone, Ynone, Ybr, Zjmp, 0}, - {Ynone, Ynone, Yi32, Zjmpcon, 1}, -} - -var yfmvd = []ytab{ - {Ym, Ynone, Yf0, Zm_o, 2}, - {Yf0, Ynone, Ym, Zo_m, 2}, - {Yrf, Ynone, Yf0, Zm_o, 2}, - {Yf0, Ynone, Yrf, Zo_m, 2}, -} - -var yfmvdp = []ytab{ - {Yf0, Ynone, Ym, Zo_m, 2}, - {Yf0, Ynone, Yrf, Zo_m, 2}, -} - -var yfmvf = []ytab{ - {Ym, Ynone, Yf0, Zm_o, 2}, - {Yf0, Ynone, Ym, Zo_m, 2}, -} - -var yfmvx = []ytab{ - {Ym, Ynone, Yf0, Zm_o, 2}, -} - -var yfmvp = []ytab{ - {Yf0, Ynone, Ym, Zo_m, 2}, -} - -var yfcmv = []ytab{ - {Yrf, Ynone, Yf0, Zm_o, 2}, -} - -var yfadd = []ytab{ - {Ym, Ynone, Yf0, Zm_o, 2}, - {Yrf, Ynone, Yf0, Zm_o, 2}, - {Yf0, Ynone, Yrf, Zo_m, 2}, -} - -var yfxch = []ytab{ - {Yf0, Ynone, Yrf, Zo_m, 2}, - {Yrf, Ynone, Yf0, Zm_o, 2}, -} - -var ycompp = []ytab{ - {Yf0, Ynone, Yrf, Zo_m, 2}, /* botch is really f0,f1 */ -} - -var ystsw = []ytab{ - {Ynone, Ynone, Ym, Zo_m, 2}, - {Ynone, Ynone, Yax, Zlit, 1}, -} - -var ysvrs = []ytab{ - {Ynone, Ynone, Ym, Zo_m, 2}, - {Ym, Ynone, Ynone, Zm_o, 2}, -} - -var ymm = []ytab{ - {Ymm, Ynone, Ymr, Zm_r_xm, 1}, - {Yxm, Ynone, Yxr, Zm_r_xm, 2}, -} - -var yxm = []ytab{ - {Yxm, Ynone, Yxr, Zm_r_xm, 1}, -} - -var yxm_q4 = []ytab{ - {Yxm, Ynone, Yxr, Zm_r, 1}, -} - -var yxcvm1 = []ytab{ - {Yxm, Ynone, Yxr, Zm_r_xm, 2}, - {Yxm, Ynone, Ymr, Zm_r_xm, 2}, -} - -var yxcvm2 = []ytab{ - {Yxm, Ynone, Yxr, Zm_r_xm, 2}, - {Ymm, Ynone, Yxr, Zm_r_xm, 2}, -} - -var yxr = []ytab{ - {Yxr, Ynone, Yxr, Zm_r_xm, 1}, -} - -var yxr_ml = []ytab{ - {Yxr, Ynone, Yml, Zr_m_xm, 1}, -} - -var ymr = []ytab{ - {Ymr, Ynone, Ymr, Zm_r, 1}, -} - -var ymr_ml = []ytab{ - {Ymr, Ynone, Yml, Zr_m_xm, 1}, -} - -var yxcmpi = []ytab{ - {Yxm, Yxr, Yi8, Zm_r_i_xm, 2}, -} - -var yxmov = []ytab{ - {Yxm, Ynone, Yxr, Zm_r_xm, 1}, - {Yxr, Ynone, Yxm, Zr_m_xm, 1}, -} - -var yxcvfl = []ytab{ - {Yxm, Ynone, Yrl, Zm_r_xm, 1}, -} - -var yxcvlf = []ytab{ - {Yml, Ynone, Yxr, Zm_r_xm, 1}, -} - -var yxcvfq = []ytab{ - {Yxm, Ynone, Yrl, Zm_r_xm, 2}, -} - -var yxcvqf = []ytab{ - {Yml, Ynone, Yxr, Zm_r_xm, 2}, -} - -var yps = []ytab{ - {Ymm, Ynone, Ymr, Zm_r_xm, 1}, - {Yi8, Ynone, Ymr, Zibo_m_xm, 2}, - {Yxm, Ynone, Yxr, Zm_r_xm, 2}, - {Yi8, Ynone, Yxr, Zibo_m_xm, 3}, -} - -var yxrrl = []ytab{ - {Yxr, Ynone, Yrl, Zm_r, 1}, -} - -var ymrxr = []ytab{ - {Ymr, Ynone, Yxr, Zm_r, 1}, - {Yxm, Ynone, Yxr, Zm_r_xm, 1}, -} - -var ymshuf = []ytab{ - {Yi8, Ymm, Ymr, Zibm_r, 2}, -} - -var ymshufb = []ytab{ - {Yxm, Ynone, Yxr, Zm2_r, 2}, -} - -var yxshuf = []ytab{ - {Yu8, Yxm, Yxr, Zibm_r, 2}, -} - -var yextrw = []ytab{ - {Yu8, Yxr, Yrl, Zibm_r, 2}, -} - -var yextr = []ytab{ - {Yu8, Yxr, Ymm, Zibr_m, 3}, -} - -var yinsrw = []ytab{ - {Yu8, Yml, Yxr, Zibm_r, 2}, -} - -var yinsr = []ytab{ - {Yu8, Ymm, Yxr, Zibm_r, 3}, -} - -var ypsdq = []ytab{ - {Yi8, Ynone, Yxr, Zibo_m, 2}, -} - -var ymskb = []ytab{ - {Yxr, Ynone, Yrl, Zm_r_xm, 2}, - {Ymr, Ynone, Yrl, Zm_r_xm, 1}, -} - -var ycrc32l = []ytab{ - {Yml, Ynone, Yrl, Zlitm_r, 0}, -} - -var yprefetch = []ytab{ - {Ym, Ynone, Ynone, Zm_o, 2}, -} - -var yaes = []ytab{ - {Yxm, Ynone, Yxr, Zlitm_r, 2}, -} - -var yxbegin = []ytab{ - {Ynone, Ynone, Ybr, Zjmp, 1}, -} - -var yxabort = []ytab{ - {Yu8, Ynone, Ynone, Zib_, 1}, -} - -var ylddqu = []ytab{ - {Ym, Ynone, Yxr, Zm_r, 1}, -} - -// VEX instructions that come in two forms: -// VTHING xmm2/m128, xmmV, xmm1 -// VTHING ymm2/m256, ymmV, ymm1 -// The opcode array in the corresponding Optab entry -// should contain the (VEX prefixes, opcode byte) pair -// for each of the two forms. -// For example, the entries for VPXOR are: -// -// VPXOR xmm2/m128, xmmV, xmm1 -// VEX.NDS.128.66.0F.WIG EF /r -// -// VPXOR ymm2/m256, ymmV, ymm1 -// VEX.NDS.256.66.0F.WIG EF /r -// -// The NDS/NDD/DDS part can be dropped, producing this -// Optab entry: -// -// {AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xEF, VEX_256_66_0F_WIG, 0xEF}} -// -var yvex_xy3 = []ytab{ - {Yxm, Yxr, Yxr, Zvex_rm_v_r, 2}, - {Yym, Yyr, Yyr, Zvex_rm_v_r, 2}, -} - -var yvex_ri3 = []ytab{ - {Yi8, Ymb, Yrl, Zvex_i_rm_r, 2}, -} - -var yvex_xyi3 = []ytab{ - {Yu8, Yxm, Yxr, Zvex_i_rm_r, 2}, - {Yu8, Yym, Yyr, Zvex_i_rm_r, 2}, - {Yi8, Yxm, Yxr, Zvex_i_rm_r, 2}, - {Yi8, Yym, Yyr, Zvex_i_rm_r, 2}, -} - -var yvex_yyi4 = []ytab{ //TODO don't hide 4 op, some version have xmm version - {Yym, Yyr, Yyr, Zvex_i_rm_v_r, 2}, -} - -var yvex_xyi4 = []ytab{ - {Yxm, Yyr, Yyr, Zvex_i_rm_v_r, 2}, -} - -var yvex_shift = []ytab{ - {Yi8, Yxr, Yxr, Zvex_i_r_v, 3}, - {Yi8, Yyr, Yyr, Zvex_i_r_v, 3}, - {Yxm, Yxr, Yxr, Zvex_rm_v_r, 2}, - {Yxm, Yyr, Yyr, Zvex_rm_v_r, 2}, -} - -var yvex_shift_dq = []ytab{ - {Yi8, Yxr, Yxr, Zvex_i_r_v, 3}, - {Yi8, Yyr, Yyr, Zvex_i_r_v, 3}, -} - -var yvex_r3 = []ytab{ - {Yml, Yrl, Yrl, Zvex_rm_v_r, 2}, -} - -var yvex_vmr3 = []ytab{ - {Yrl, Yml, Yrl, Zvex_v_rm_r, 2}, -} - -var yvex_xy2 = []ytab{ - {Yxm, Ynone, Yxr, Zvex_rm_v_r, 2}, - {Yym, Ynone, Yyr, Zvex_rm_v_r, 2}, -} - -var yvex_xyr2 = []ytab{ - {Yxr, Ynone, Yrl, Zvex_rm_v_r, 2}, - {Yyr, Ynone, Yrl, Zvex_rm_v_r, 2}, -} - -var yvex_vmovdqa = []ytab{ - {Yxm, Ynone, Yxr, Zvex_rm_v_r, 2}, - {Yxr, Ynone, Yxm, Zvex_r_v_rm, 2}, - {Yym, Ynone, Yyr, Zvex_rm_v_r, 2}, - {Yyr, Ynone, Yym, Zvex_r_v_rm, 2}, -} - -var yvex_vmovntdq = []ytab{ - {Yxr, Ynone, Ym, Zvex_r_v_rm, 2}, - {Yyr, Ynone, Ym, Zvex_r_v_rm, 2}, -} - -var yvex_vpbroadcast = []ytab{ - {Yxm, Ynone, Yxr, Zvex_rm_v_r, 2}, - {Yxm, Ynone, Yyr, Zvex_rm_v_r, 2}, -} - -var yvex_vpbroadcast_sd = []ytab{ - {Yxm, Ynone, Yyr, Zvex_rm_v_r, 2}, -} - -var ymmxmm0f38 = []ytab{ - {Ymm, Ynone, Ymr, Zlitm_r, 3}, - {Yxm, Ynone, Yxr, Zlitm_r, 5}, -} - -/* - * You are doasm, holding in your hand a Prog* with p->as set to, say, ACRC32, - * and p->from and p->to as operands (Addr*). The linker scans optab to find - * the entry with the given p->as and then looks through the ytable for that - * instruction (the second field in the optab struct) for a line whose first - * two values match the Ytypes of the p->from and p->to operands. The function - * oclass in span.c computes the specific Ytype of an operand and then the set - * of more general Ytypes that it satisfies is implied by the ycover table, set - * up in instinit. For example, oclass distinguishes the constants 0 and 1 - * from the more general 8-bit constants, but instinit says - * - * ycover[Yi0*Ymax + Ys32] = 1; - * ycover[Yi1*Ymax + Ys32] = 1; - * ycover[Yi8*Ymax + Ys32] = 1; - * - * which means that Yi0, Yi1, and Yi8 all count as Ys32 (signed 32) - * if that's what an instruction can handle. - * - * In parallel with the scan through the ytable for the appropriate line, there - * is a z pointer that starts out pointing at the strange magic byte list in - * the Optab struct. With each step past a non-matching ytable line, z - * advances by the 4th entry in the line. When a matching line is found, that - * z pointer has the extra data to use in laying down the instruction bytes. - * The actual bytes laid down are a function of the 3rd entry in the line (that - * is, the Ztype) and the z bytes. - * - * For example, let's look at AADDL. The optab line says: - * { AADDL, yaddl, Px, 0x83,(00),0x05,0x81,(00),0x01,0x03 }, - * - * and yaddl says - * uchar yaddl[] = - * { - * Yi8, Yml, Zibo_m, 2, - * Yi32, Yax, Zil_, 1, - * Yi32, Yml, Zilo_m, 2, - * Yrl, Yml, Zr_m, 1, - * Yml, Yrl, Zm_r, 1, - * 0 - * }; - * - * so there are 5 possible types of ADDL instruction that can be laid down, and - * possible states used to lay them down (Ztype and z pointer, assuming z - * points at {0x83,(00),0x05,0x81,(00),0x01,0x03}) are: - * - * Yi8, Yml -> Zibo_m, z (0x83, 00) - * Yi32, Yax -> Zil_, z+2 (0x05) - * Yi32, Yml -> Zilo_m, z+2+1 (0x81, 0x00) - * Yrl, Yml -> Zr_m, z+2+1+2 (0x01) - * Yml, Yrl -> Zm_r, z+2+1+2+1 (0x03) - * - * The Pconstant in the optab line controls the prefix bytes to emit. That's - * relatively straightforward as this program goes. - * - * The switch on t[2] in doasm implements the various Z cases. Zibo_m, for - * example, is an opcode byte (z[0]) then an asmando (which is some kind of - * encoded addressing mode for the Yml arg), and then a single immediate byte. - * Zilo_m is the same but a long (32-bit) immediate. - */ -var optab = -/* as, ytab, andproto, opcode */ -[]Optab{ - {obj.AXXX, nil, 0, [23]uint8{}}, - {AAAA, ynone, P32, [23]uint8{0x37}}, - {AAAD, ynone, P32, [23]uint8{0xd5, 0x0a}}, - {AAAM, ynone, P32, [23]uint8{0xd4, 0x0a}}, - {AAAS, ynone, P32, [23]uint8{0x3f}}, - {AADCB, yxorb, Pb, [23]uint8{0x14, 0x80, 02, 0x10, 0x10}}, - {AADCL, yaddl, Px, [23]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}}, - {AADCQ, yaddl, Pw, [23]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}}, - {AADCW, yaddl, Pe, [23]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}}, - {AADDB, yxorb, Pb, [23]uint8{0x04, 0x80, 00, 0x00, 0x02}}, - {AADDL, yaddl, Px, [23]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}}, - {AADDPD, yxm, Pq, [23]uint8{0x58}}, - {AADDPS, yxm, Pm, [23]uint8{0x58}}, - {AADDQ, yaddl, Pw, [23]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}}, - {AADDSD, yxm, Pf2, [23]uint8{0x58}}, - {AADDSS, yxm, Pf3, [23]uint8{0x58}}, - {AADDW, yaddl, Pe, [23]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}}, - {AADJSP, nil, 0, [23]uint8{}}, - {AANDB, yxorb, Pb, [23]uint8{0x24, 0x80, 04, 0x20, 0x22}}, - {AANDL, yaddl, Px, [23]uint8{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}}, - {AANDNPD, yxm, Pq, [23]uint8{0x55}}, - {AANDNPS, yxm, Pm, [23]uint8{0x55}}, - {AANDPD, yxm, Pq, [23]uint8{0x54}}, - {AANDPS, yxm, Pq, [23]uint8{0x54}}, - {AANDQ, yaddl, Pw, [23]uint8{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}}, - {AANDW, yaddl, Pe, [23]uint8{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}}, - {AARPL, yrl_ml, P32, [23]uint8{0x63}}, - {ABOUNDL, yrl_m, P32, [23]uint8{0x62}}, - {ABOUNDW, yrl_m, Pe, [23]uint8{0x62}}, - {ABSFL, yml_rl, Pm, [23]uint8{0xbc}}, - {ABSFQ, yml_rl, Pw, [23]uint8{0x0f, 0xbc}}, - {ABSFW, yml_rl, Pq, [23]uint8{0xbc}}, - {ABSRL, yml_rl, Pm, [23]uint8{0xbd}}, - {ABSRQ, yml_rl, Pw, [23]uint8{0x0f, 0xbd}}, - {ABSRW, yml_rl, Pq, [23]uint8{0xbd}}, - {ABSWAPL, ybswap, Px, [23]uint8{0x0f, 0xc8}}, - {ABSWAPQ, ybswap, Pw, [23]uint8{0x0f, 0xc8}}, - {ABTCL, ybtl, Pm, [23]uint8{0xba, 07, 0xbb}}, - {ABTCQ, ybtl, Pw, [23]uint8{0x0f, 0xba, 07, 0x0f, 0xbb}}, - {ABTCW, ybtl, Pq, [23]uint8{0xba, 07, 0xbb}}, - {ABTL, ybtl, Pm, [23]uint8{0xba, 04, 0xa3}}, - {ABTQ, ybtl, Pw, [23]uint8{0x0f, 0xba, 04, 0x0f, 0xa3}}, - {ABTRL, ybtl, Pm, [23]uint8{0xba, 06, 0xb3}}, - {ABTRQ, ybtl, Pw, [23]uint8{0x0f, 0xba, 06, 0x0f, 0xb3}}, - {ABTRW, ybtl, Pq, [23]uint8{0xba, 06, 0xb3}}, - {ABTSL, ybtl, Pm, [23]uint8{0xba, 05, 0xab}}, - {ABTSQ, ybtl, Pw, [23]uint8{0x0f, 0xba, 05, 0x0f, 0xab}}, - {ABTSW, ybtl, Pq, [23]uint8{0xba, 05, 0xab}}, - {ABTW, ybtl, Pq, [23]uint8{0xba, 04, 0xa3}}, - {ABYTE, ybyte, Px, [23]uint8{1}}, - {obj.ACALL, ycall, Px, [23]uint8{0xff, 02, 0xff, 0x15, 0xe8}}, - {ACDQ, ynone, Px, [23]uint8{0x99}}, - {ACLC, ynone, Px, [23]uint8{0xf8}}, - {ACLD, ynone, Px, [23]uint8{0xfc}}, - {ACLI, ynone, Px, [23]uint8{0xfa}}, - {ACLTS, ynone, Pm, [23]uint8{0x06}}, - {ACMC, ynone, Px, [23]uint8{0xf5}}, - {ACMOVLCC, yml_rl, Pm, [23]uint8{0x43}}, - {ACMOVLCS, yml_rl, Pm, [23]uint8{0x42}}, - {ACMOVLEQ, yml_rl, Pm, [23]uint8{0x44}}, - {ACMOVLGE, yml_rl, Pm, [23]uint8{0x4d}}, - {ACMOVLGT, yml_rl, Pm, [23]uint8{0x4f}}, - {ACMOVLHI, yml_rl, Pm, [23]uint8{0x47}}, - {ACMOVLLE, yml_rl, Pm, [23]uint8{0x4e}}, - {ACMOVLLS, yml_rl, Pm, [23]uint8{0x46}}, - {ACMOVLLT, yml_rl, Pm, [23]uint8{0x4c}}, - {ACMOVLMI, yml_rl, Pm, [23]uint8{0x48}}, - {ACMOVLNE, yml_rl, Pm, [23]uint8{0x45}}, - {ACMOVLOC, yml_rl, Pm, [23]uint8{0x41}}, - {ACMOVLOS, yml_rl, Pm, [23]uint8{0x40}}, - {ACMOVLPC, yml_rl, Pm, [23]uint8{0x4b}}, - {ACMOVLPL, yml_rl, Pm, [23]uint8{0x49}}, - {ACMOVLPS, yml_rl, Pm, [23]uint8{0x4a}}, - {ACMOVQCC, yml_rl, Pw, [23]uint8{0x0f, 0x43}}, - {ACMOVQCS, yml_rl, Pw, [23]uint8{0x0f, 0x42}}, - {ACMOVQEQ, yml_rl, Pw, [23]uint8{0x0f, 0x44}}, - {ACMOVQGE, yml_rl, Pw, [23]uint8{0x0f, 0x4d}}, - {ACMOVQGT, yml_rl, Pw, [23]uint8{0x0f, 0x4f}}, - {ACMOVQHI, yml_rl, Pw, [23]uint8{0x0f, 0x47}}, - {ACMOVQLE, yml_rl, Pw, [23]uint8{0x0f, 0x4e}}, - {ACMOVQLS, yml_rl, Pw, [23]uint8{0x0f, 0x46}}, - {ACMOVQLT, yml_rl, Pw, [23]uint8{0x0f, 0x4c}}, - {ACMOVQMI, yml_rl, Pw, [23]uint8{0x0f, 0x48}}, - {ACMOVQNE, yml_rl, Pw, [23]uint8{0x0f, 0x45}}, - {ACMOVQOC, yml_rl, Pw, [23]uint8{0x0f, 0x41}}, - {ACMOVQOS, yml_rl, Pw, [23]uint8{0x0f, 0x40}}, - {ACMOVQPC, yml_rl, Pw, [23]uint8{0x0f, 0x4b}}, - {ACMOVQPL, yml_rl, Pw, [23]uint8{0x0f, 0x49}}, - {ACMOVQPS, yml_rl, Pw, [23]uint8{0x0f, 0x4a}}, - {ACMOVWCC, yml_rl, Pq, [23]uint8{0x43}}, - {ACMOVWCS, yml_rl, Pq, [23]uint8{0x42}}, - {ACMOVWEQ, yml_rl, Pq, [23]uint8{0x44}}, - {ACMOVWGE, yml_rl, Pq, [23]uint8{0x4d}}, - {ACMOVWGT, yml_rl, Pq, [23]uint8{0x4f}}, - {ACMOVWHI, yml_rl, Pq, [23]uint8{0x47}}, - {ACMOVWLE, yml_rl, Pq, [23]uint8{0x4e}}, - {ACMOVWLS, yml_rl, Pq, [23]uint8{0x46}}, - {ACMOVWLT, yml_rl, Pq, [23]uint8{0x4c}}, - {ACMOVWMI, yml_rl, Pq, [23]uint8{0x48}}, - {ACMOVWNE, yml_rl, Pq, [23]uint8{0x45}}, - {ACMOVWOC, yml_rl, Pq, [23]uint8{0x41}}, - {ACMOVWOS, yml_rl, Pq, [23]uint8{0x40}}, - {ACMOVWPC, yml_rl, Pq, [23]uint8{0x4b}}, - {ACMOVWPL, yml_rl, Pq, [23]uint8{0x49}}, - {ACMOVWPS, yml_rl, Pq, [23]uint8{0x4a}}, - {ACMPB, ycmpb, Pb, [23]uint8{0x3c, 0x80, 07, 0x38, 0x3a}}, - {ACMPL, ycmpl, Px, [23]uint8{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}}, - {ACMPPD, yxcmpi, Px, [23]uint8{Pe, 0xc2}}, - {ACMPPS, yxcmpi, Pm, [23]uint8{0xc2, 0}}, - {ACMPQ, ycmpl, Pw, [23]uint8{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}}, - {ACMPSB, ynone, Pb, [23]uint8{0xa6}}, - {ACMPSD, yxcmpi, Px, [23]uint8{Pf2, 0xc2}}, - {ACMPSL, ynone, Px, [23]uint8{0xa7}}, - {ACMPSQ, ynone, Pw, [23]uint8{0xa7}}, - {ACMPSS, yxcmpi, Px, [23]uint8{Pf3, 0xc2}}, - {ACMPSW, ynone, Pe, [23]uint8{0xa7}}, - {ACMPW, ycmpl, Pe, [23]uint8{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}}, - {ACOMISD, yxm, Pe, [23]uint8{0x2f}}, - {ACOMISS, yxm, Pm, [23]uint8{0x2f}}, - {ACPUID, ynone, Pm, [23]uint8{0xa2}}, - {ACVTPL2PD, yxcvm2, Px, [23]uint8{Pf3, 0xe6, Pe, 0x2a}}, - {ACVTPL2PS, yxcvm2, Pm, [23]uint8{0x5b, 0, 0x2a, 0}}, - {ACVTPD2PL, yxcvm1, Px, [23]uint8{Pf2, 0xe6, Pe, 0x2d}}, - {ACVTPD2PS, yxm, Pe, [23]uint8{0x5a}}, - {ACVTPS2PL, yxcvm1, Px, [23]uint8{Pe, 0x5b, Pm, 0x2d}}, - {ACVTPS2PD, yxm, Pm, [23]uint8{0x5a}}, - {ACVTSD2SL, yxcvfl, Pf2, [23]uint8{0x2d}}, - {ACVTSD2SQ, yxcvfq, Pw, [23]uint8{Pf2, 0x2d}}, - {ACVTSD2SS, yxm, Pf2, [23]uint8{0x5a}}, - {ACVTSL2SD, yxcvlf, Pf2, [23]uint8{0x2a}}, - {ACVTSQ2SD, yxcvqf, Pw, [23]uint8{Pf2, 0x2a}}, - {ACVTSL2SS, yxcvlf, Pf3, [23]uint8{0x2a}}, - {ACVTSQ2SS, yxcvqf, Pw, [23]uint8{Pf3, 0x2a}}, - {ACVTSS2SD, yxm, Pf3, [23]uint8{0x5a}}, - {ACVTSS2SL, yxcvfl, Pf3, [23]uint8{0x2d}}, - {ACVTSS2SQ, yxcvfq, Pw, [23]uint8{Pf3, 0x2d}}, - {ACVTTPD2PL, yxcvm1, Px, [23]uint8{Pe, 0xe6, Pe, 0x2c}}, - {ACVTTPS2PL, yxcvm1, Px, [23]uint8{Pf3, 0x5b, Pm, 0x2c}}, - {ACVTTSD2SL, yxcvfl, Pf2, [23]uint8{0x2c}}, - {ACVTTSD2SQ, yxcvfq, Pw, [23]uint8{Pf2, 0x2c}}, - {ACVTTSS2SL, yxcvfl, Pf3, [23]uint8{0x2c}}, - {ACVTTSS2SQ, yxcvfq, Pw, [23]uint8{Pf3, 0x2c}}, - {ACWD, ynone, Pe, [23]uint8{0x99}}, - {ACQO, ynone, Pw, [23]uint8{0x99}}, - {ADAA, ynone, P32, [23]uint8{0x27}}, - {ADAS, ynone, P32, [23]uint8{0x2f}}, - {ADECB, yscond, Pb, [23]uint8{0xfe, 01}}, - {ADECL, yincl, Px1, [23]uint8{0x48, 0xff, 01}}, - {ADECQ, yincq, Pw, [23]uint8{0xff, 01}}, - {ADECW, yincq, Pe, [23]uint8{0xff, 01}}, - {ADIVB, ydivb, Pb, [23]uint8{0xf6, 06}}, - {ADIVL, ydivl, Px, [23]uint8{0xf7, 06}}, - {ADIVPD, yxm, Pe, [23]uint8{0x5e}}, - {ADIVPS, yxm, Pm, [23]uint8{0x5e}}, - {ADIVQ, ydivl, Pw, [23]uint8{0xf7, 06}}, - {ADIVSD, yxm, Pf2, [23]uint8{0x5e}}, - {ADIVSS, yxm, Pf3, [23]uint8{0x5e}}, - {ADIVW, ydivl, Pe, [23]uint8{0xf7, 06}}, - {AEMMS, ynone, Pm, [23]uint8{0x77}}, - {AENTER, nil, 0, [23]uint8{}}, /* botch */ - {AFXRSTOR, ysvrs, Pm, [23]uint8{0xae, 01, 0xae, 01}}, - {AFXSAVE, ysvrs, Pm, [23]uint8{0xae, 00, 0xae, 00}}, - {AFXRSTOR64, ysvrs, Pw, [23]uint8{0x0f, 0xae, 01, 0x0f, 0xae, 01}}, - {AFXSAVE64, ysvrs, Pw, [23]uint8{0x0f, 0xae, 00, 0x0f, 0xae, 00}}, - {AHLT, ynone, Px, [23]uint8{0xf4}}, - {AIDIVB, ydivb, Pb, [23]uint8{0xf6, 07}}, - {AIDIVL, ydivl, Px, [23]uint8{0xf7, 07}}, - {AIDIVQ, ydivl, Pw, [23]uint8{0xf7, 07}}, - {AIDIVW, ydivl, Pe, [23]uint8{0xf7, 07}}, - {AIMULB, ydivb, Pb, [23]uint8{0xf6, 05}}, - {AIMULL, yimul, Px, [23]uint8{0xf7, 05, 0x6b, 0x69, Pm, 0xaf}}, - {AIMULQ, yimul, Pw, [23]uint8{0xf7, 05, 0x6b, 0x69, Pm, 0xaf}}, - {AIMULW, yimul, Pe, [23]uint8{0xf7, 05, 0x6b, 0x69, Pm, 0xaf}}, - {AIMUL3Q, yimul3, Pw, [23]uint8{0x6b, 00}}, - {AINB, yin, Pb, [23]uint8{0xe4, 0xec}}, - {AINCB, yscond, Pb, [23]uint8{0xfe, 00}}, - {AINCL, yincl, Px1, [23]uint8{0x40, 0xff, 00}}, - {AINCQ, yincq, Pw, [23]uint8{0xff, 00}}, - {AINCW, yincq, Pe, [23]uint8{0xff, 00}}, - {AINL, yin, Px, [23]uint8{0xe5, 0xed}}, - {AINSB, ynone, Pb, [23]uint8{0x6c}}, - {AINSL, ynone, Px, [23]uint8{0x6d}}, - {AINSW, ynone, Pe, [23]uint8{0x6d}}, - {AINT, yint, Px, [23]uint8{0xcd}}, - {AINTO, ynone, P32, [23]uint8{0xce}}, - {AINW, yin, Pe, [23]uint8{0xe5, 0xed}}, - {AIRETL, ynone, Px, [23]uint8{0xcf}}, - {AIRETQ, ynone, Pw, [23]uint8{0xcf}}, - {AIRETW, ynone, Pe, [23]uint8{0xcf}}, - {AJCC, yjcond, Px, [23]uint8{0x73, 0x83, 00}}, - {AJCS, yjcond, Px, [23]uint8{0x72, 0x82}}, - {AJCXZL, yloop, Px, [23]uint8{0xe3}}, - {AJCXZW, yloop, Px, [23]uint8{0xe3}}, - {AJCXZQ, yloop, Px, [23]uint8{0xe3}}, - {AJEQ, yjcond, Px, [23]uint8{0x74, 0x84}}, - {AJGE, yjcond, Px, [23]uint8{0x7d, 0x8d}}, - {AJGT, yjcond, Px, [23]uint8{0x7f, 0x8f}}, - {AJHI, yjcond, Px, [23]uint8{0x77, 0x87}}, - {AJLE, yjcond, Px, [23]uint8{0x7e, 0x8e}}, - {AJLS, yjcond, Px, [23]uint8{0x76, 0x86}}, - {AJLT, yjcond, Px, [23]uint8{0x7c, 0x8c}}, - {AJMI, yjcond, Px, [23]uint8{0x78, 0x88}}, - {obj.AJMP, yjmp, Px, [23]uint8{0xff, 04, 0xeb, 0xe9}}, - {AJNE, yjcond, Px, [23]uint8{0x75, 0x85}}, - {AJOC, yjcond, Px, [23]uint8{0x71, 0x81, 00}}, - {AJOS, yjcond, Px, [23]uint8{0x70, 0x80, 00}}, - {AJPC, yjcond, Px, [23]uint8{0x7b, 0x8b}}, - {AJPL, yjcond, Px, [23]uint8{0x79, 0x89}}, - {AJPS, yjcond, Px, [23]uint8{0x7a, 0x8a}}, - {AHADDPD, yxm, Pq, [23]uint8{0x7c}}, - {AHADDPS, yxm, Pf2, [23]uint8{0x7c}}, - {AHSUBPD, yxm, Pq, [23]uint8{0x7d}}, - {AHSUBPS, yxm, Pf2, [23]uint8{0x7d}}, - {ALAHF, ynone, Px, [23]uint8{0x9f}}, - {ALARL, yml_rl, Pm, [23]uint8{0x02}}, - {ALARW, yml_rl, Pq, [23]uint8{0x02}}, - {ALDDQU, ylddqu, Pf2, [23]uint8{0xf0}}, - {ALDMXCSR, ysvrs, Pm, [23]uint8{0xae, 02, 0xae, 02}}, - {ALEAL, ym_rl, Px, [23]uint8{0x8d}}, - {ALEAQ, ym_rl, Pw, [23]uint8{0x8d}}, - {ALEAVEL, ynone, P32, [23]uint8{0xc9}}, - {ALEAVEQ, ynone, Py, [23]uint8{0xc9}}, - {ALEAVEW, ynone, Pe, [23]uint8{0xc9}}, - {ALEAW, ym_rl, Pe, [23]uint8{0x8d}}, - {ALOCK, ynone, Px, [23]uint8{0xf0}}, - {ALODSB, ynone, Pb, [23]uint8{0xac}}, - {ALODSL, ynone, Px, [23]uint8{0xad}}, - {ALODSQ, ynone, Pw, [23]uint8{0xad}}, - {ALODSW, ynone, Pe, [23]uint8{0xad}}, - {ALONG, ybyte, Px, [23]uint8{4}}, - {ALOOP, yloop, Px, [23]uint8{0xe2}}, - {ALOOPEQ, yloop, Px, [23]uint8{0xe1}}, - {ALOOPNE, yloop, Px, [23]uint8{0xe0}}, - {ALSLL, yml_rl, Pm, [23]uint8{0x03}}, - {ALSLW, yml_rl, Pq, [23]uint8{0x03}}, - {AMASKMOVOU, yxr, Pe, [23]uint8{0xf7}}, - {AMASKMOVQ, ymr, Pm, [23]uint8{0xf7}}, - {AMAXPD, yxm, Pe, [23]uint8{0x5f}}, - {AMAXPS, yxm, Pm, [23]uint8{0x5f}}, - {AMAXSD, yxm, Pf2, [23]uint8{0x5f}}, - {AMAXSS, yxm, Pf3, [23]uint8{0x5f}}, - {AMINPD, yxm, Pe, [23]uint8{0x5d}}, - {AMINPS, yxm, Pm, [23]uint8{0x5d}}, - {AMINSD, yxm, Pf2, [23]uint8{0x5d}}, - {AMINSS, yxm, Pf3, [23]uint8{0x5d}}, - {AMOVAPD, yxmov, Pe, [23]uint8{0x28, 0x29}}, - {AMOVAPS, yxmov, Pm, [23]uint8{0x28, 0x29}}, - {AMOVB, ymovb, Pb, [23]uint8{0x88, 0x8a, 0xb0, 0xc6, 00}}, - {AMOVBLSX, ymb_rl, Pm, [23]uint8{0xbe}}, - {AMOVBLZX, ymb_rl, Pm, [23]uint8{0xb6}}, - {AMOVBQSX, ymb_rl, Pw, [23]uint8{0x0f, 0xbe}}, - {AMOVBQZX, ymb_rl, Pm, [23]uint8{0xb6}}, - {AMOVBWSX, ymb_rl, Pq, [23]uint8{0xbe}}, - {AMOVBWZX, ymb_rl, Pq, [23]uint8{0xb6}}, - {AMOVO, yxmov, Pe, [23]uint8{0x6f, 0x7f}}, - {AMOVOU, yxmov, Pf3, [23]uint8{0x6f, 0x7f}}, - {AMOVHLPS, yxr, Pm, [23]uint8{0x12}}, - {AMOVHPD, yxmov, Pe, [23]uint8{0x16, 0x17}}, - {AMOVHPS, yxmov, Pm, [23]uint8{0x16, 0x17}}, - {AMOVL, ymovl, Px, [23]uint8{0x89, 0x8b, 0x31, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}}, - {AMOVLHPS, yxr, Pm, [23]uint8{0x16}}, - {AMOVLPD, yxmov, Pe, [23]uint8{0x12, 0x13}}, - {AMOVLPS, yxmov, Pm, [23]uint8{0x12, 0x13}}, - {AMOVLQSX, yml_rl, Pw, [23]uint8{0x63}}, - {AMOVLQZX, yml_rl, Px, [23]uint8{0x8b}}, - {AMOVMSKPD, yxrrl, Pq, [23]uint8{0x50}}, - {AMOVMSKPS, yxrrl, Pm, [23]uint8{0x50}}, - {AMOVNTO, yxr_ml, Pe, [23]uint8{0xe7}}, - {AMOVNTPD, yxr_ml, Pe, [23]uint8{0x2b}}, - {AMOVNTPS, yxr_ml, Pm, [23]uint8{0x2b}}, - {AMOVNTQ, ymr_ml, Pm, [23]uint8{0xe7}}, - {AMOVQ, ymovq, Pw8, [23]uint8{0x6f, 0x7f, Pf2, 0xd6, Pf3, 0x7e, Pe, 0xd6, 0x89, 0x8b, 0x31, 0xc7, 00, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}}, - {AMOVQOZX, ymrxr, Pf3, [23]uint8{0xd6, 0x7e}}, - {AMOVSB, ynone, Pb, [23]uint8{0xa4}}, - {AMOVSD, yxmov, Pf2, [23]uint8{0x10, 0x11}}, - {AMOVSL, ynone, Px, [23]uint8{0xa5}}, - {AMOVSQ, ynone, Pw, [23]uint8{0xa5}}, - {AMOVSS, yxmov, Pf3, [23]uint8{0x10, 0x11}}, - {AMOVSW, ynone, Pe, [23]uint8{0xa5}}, - {AMOVUPD, yxmov, Pe, [23]uint8{0x10, 0x11}}, - {AMOVUPS, yxmov, Pm, [23]uint8{0x10, 0x11}}, - {AMOVW, ymovw, Pe, [23]uint8{0x89, 0x8b, 0x31, 0xb8, 0xc7, 00, 0}}, - {AMOVWLSX, yml_rl, Pm, [23]uint8{0xbf}}, - {AMOVWLZX, yml_rl, Pm, [23]uint8{0xb7}}, - {AMOVWQSX, yml_rl, Pw, [23]uint8{0x0f, 0xbf}}, - {AMOVWQZX, yml_rl, Pw, [23]uint8{0x0f, 0xb7}}, - {AMULB, ydivb, Pb, [23]uint8{0xf6, 04}}, - {AMULL, ydivl, Px, [23]uint8{0xf7, 04}}, - {AMULPD, yxm, Pe, [23]uint8{0x59}}, - {AMULPS, yxm, Ym, [23]uint8{0x59}}, - {AMULQ, ydivl, Pw, [23]uint8{0xf7, 04}}, - {AMULSD, yxm, Pf2, [23]uint8{0x59}}, - {AMULSS, yxm, Pf3, [23]uint8{0x59}}, - {AMULW, ydivl, Pe, [23]uint8{0xf7, 04}}, - {ANEGB, yscond, Pb, [23]uint8{0xf6, 03}}, - {ANEGL, yscond, Px, [23]uint8{0xf7, 03}}, - {ANEGQ, yscond, Pw, [23]uint8{0xf7, 03}}, - {ANEGW, yscond, Pe, [23]uint8{0xf7, 03}}, - {obj.ANOP, ynop, Px, [23]uint8{0, 0}}, - {ANOTB, yscond, Pb, [23]uint8{0xf6, 02}}, - {ANOTL, yscond, Px, [23]uint8{0xf7, 02}}, // TODO(rsc): yscond is wrong here. - {ANOTQ, yscond, Pw, [23]uint8{0xf7, 02}}, - {ANOTW, yscond, Pe, [23]uint8{0xf7, 02}}, - {AORB, yxorb, Pb, [23]uint8{0x0c, 0x80, 01, 0x08, 0x0a}}, - {AORL, yaddl, Px, [23]uint8{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}}, - {AORPD, yxm, Pq, [23]uint8{0x56}}, - {AORPS, yxm, Pm, [23]uint8{0x56}}, - {AORQ, yaddl, Pw, [23]uint8{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}}, - {AORW, yaddl, Pe, [23]uint8{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}}, - {AOUTB, yin, Pb, [23]uint8{0xe6, 0xee}}, - {AOUTL, yin, Px, [23]uint8{0xe7, 0xef}}, - {AOUTSB, ynone, Pb, [23]uint8{0x6e}}, - {AOUTSL, ynone, Px, [23]uint8{0x6f}}, - {AOUTSW, ynone, Pe, [23]uint8{0x6f}}, - {AOUTW, yin, Pe, [23]uint8{0xe7, 0xef}}, - {APACKSSLW, ymm, Py1, [23]uint8{0x6b, Pe, 0x6b}}, - {APACKSSWB, ymm, Py1, [23]uint8{0x63, Pe, 0x63}}, - {APACKUSWB, ymm, Py1, [23]uint8{0x67, Pe, 0x67}}, - {APADDB, ymm, Py1, [23]uint8{0xfc, Pe, 0xfc}}, - {APADDL, ymm, Py1, [23]uint8{0xfe, Pe, 0xfe}}, - {APADDQ, yxm, Pe, [23]uint8{0xd4}}, - {APADDSB, ymm, Py1, [23]uint8{0xec, Pe, 0xec}}, - {APADDSW, ymm, Py1, [23]uint8{0xed, Pe, 0xed}}, - {APADDUSB, ymm, Py1, [23]uint8{0xdc, Pe, 0xdc}}, - {APADDUSW, ymm, Py1, [23]uint8{0xdd, Pe, 0xdd}}, - {APADDW, ymm, Py1, [23]uint8{0xfd, Pe, 0xfd}}, - {APAND, ymm, Py1, [23]uint8{0xdb, Pe, 0xdb}}, - {APANDN, ymm, Py1, [23]uint8{0xdf, Pe, 0xdf}}, - {APAUSE, ynone, Px, [23]uint8{0xf3, 0x90}}, - {APAVGB, ymm, Py1, [23]uint8{0xe0, Pe, 0xe0}}, - {APAVGW, ymm, Py1, [23]uint8{0xe3, Pe, 0xe3}}, - {APCMPEQB, ymm, Py1, [23]uint8{0x74, Pe, 0x74}}, - {APCMPEQL, ymm, Py1, [23]uint8{0x76, Pe, 0x76}}, - {APCMPEQW, ymm, Py1, [23]uint8{0x75, Pe, 0x75}}, - {APCMPGTB, ymm, Py1, [23]uint8{0x64, Pe, 0x64}}, - {APCMPGTL, ymm, Py1, [23]uint8{0x66, Pe, 0x66}}, - {APCMPGTW, ymm, Py1, [23]uint8{0x65, Pe, 0x65}}, - {APEXTRW, yextrw, Pq, [23]uint8{0xc5, 00}}, - {APEXTRB, yextr, Pq, [23]uint8{0x3a, 0x14, 00}}, - {APEXTRD, yextr, Pq, [23]uint8{0x3a, 0x16, 00}}, - {APEXTRQ, yextr, Pq3, [23]uint8{0x3a, 0x16, 00}}, - {APHADDD, ymmxmm0f38, Px, [23]uint8{0x0F, 0x38, 0x02, 0, 0x66, 0x0F, 0x38, 0x02, 0}}, - {APHADDSW, yxm_q4, Pq4, [23]uint8{0x03}}, - {APHADDW, yxm_q4, Pq4, [23]uint8{0x01}}, - {APHMINPOSUW, yxm_q4, Pq4, [23]uint8{0x41}}, - {APHSUBD, yxm_q4, Pq4, [23]uint8{0x06}}, - {APHSUBSW, yxm_q4, Pq4, [23]uint8{0x07}}, - {APHSUBW, yxm_q4, Pq4, [23]uint8{0x05}}, - {APINSRW, yinsrw, Pq, [23]uint8{0xc4, 00}}, - {APINSRB, yinsr, Pq, [23]uint8{0x3a, 0x20, 00}}, - {APINSRD, yinsr, Pq, [23]uint8{0x3a, 0x22, 00}}, - {APINSRQ, yinsr, Pq3, [23]uint8{0x3a, 0x22, 00}}, - {APMADDWL, ymm, Py1, [23]uint8{0xf5, Pe, 0xf5}}, - {APMAXSW, yxm, Pe, [23]uint8{0xee}}, - {APMAXUB, yxm, Pe, [23]uint8{0xde}}, - {APMINSW, yxm, Pe, [23]uint8{0xea}}, - {APMINUB, yxm, Pe, [23]uint8{0xda}}, - {APMOVMSKB, ymskb, Px, [23]uint8{Pe, 0xd7, 0xd7}}, - {APMOVSXBD, yxm_q4, Pq4, [23]uint8{0x21}}, - {APMOVSXBQ, yxm_q4, Pq4, [23]uint8{0x22}}, - {APMOVSXBW, yxm_q4, Pq4, [23]uint8{0x20}}, - {APMOVSXDQ, yxm_q4, Pq4, [23]uint8{0x25}}, - {APMOVSXWD, yxm_q4, Pq4, [23]uint8{0x23}}, - {APMOVSXWQ, yxm_q4, Pq4, [23]uint8{0x24}}, - {APMOVZXBD, yxm_q4, Pq4, [23]uint8{0x31}}, - {APMOVZXBQ, yxm_q4, Pq4, [23]uint8{0x32}}, - {APMOVZXBW, yxm_q4, Pq4, [23]uint8{0x30}}, - {APMOVZXDQ, yxm_q4, Pq4, [23]uint8{0x35}}, - {APMOVZXWD, yxm_q4, Pq4, [23]uint8{0x33}}, - {APMOVZXWQ, yxm_q4, Pq4, [23]uint8{0x34}}, - {APMULDQ, yxm_q4, Pq4, [23]uint8{0x28}}, - {APMULHUW, ymm, Py1, [23]uint8{0xe4, Pe, 0xe4}}, - {APMULHW, ymm, Py1, [23]uint8{0xe5, Pe, 0xe5}}, - {APMULLD, yxm_q4, Pq4, [23]uint8{0x40}}, - {APMULLW, ymm, Py1, [23]uint8{0xd5, Pe, 0xd5}}, - {APMULULQ, ymm, Py1, [23]uint8{0xf4, Pe, 0xf4}}, - {APOPAL, ynone, P32, [23]uint8{0x61}}, - {APOPAW, ynone, Pe, [23]uint8{0x61}}, - {APOPCNTW, yml_rl, Pef3, [23]uint8{0xb8}}, - {APOPCNTL, yml_rl, Pf3, [23]uint8{0xb8}}, - {APOPCNTQ, yml_rl, Pfw, [23]uint8{0xb8}}, - {APOPFL, ynone, P32, [23]uint8{0x9d}}, - {APOPFQ, ynone, Py, [23]uint8{0x9d}}, - {APOPFW, ynone, Pe, [23]uint8{0x9d}}, - {APOPL, ypopl, P32, [23]uint8{0x58, 0x8f, 00}}, - {APOPQ, ypopl, Py, [23]uint8{0x58, 0x8f, 00}}, - {APOPW, ypopl, Pe, [23]uint8{0x58, 0x8f, 00}}, - {APOR, ymm, Py1, [23]uint8{0xeb, Pe, 0xeb}}, - {APSADBW, yxm, Pq, [23]uint8{0xf6}}, - {APSHUFHW, yxshuf, Pf3, [23]uint8{0x70, 00}}, - {APSHUFL, yxshuf, Pq, [23]uint8{0x70, 00}}, - {APSHUFLW, yxshuf, Pf2, [23]uint8{0x70, 00}}, - {APSHUFW, ymshuf, Pm, [23]uint8{0x70, 00}}, - {APSHUFB, ymshufb, Pq, [23]uint8{0x38, 0x00}}, - {APSLLO, ypsdq, Pq, [23]uint8{0x73, 07}}, - {APSLLL, yps, Py3, [23]uint8{0xf2, 0x72, 06, Pe, 0xf2, Pe, 0x72, 06}}, - {APSLLQ, yps, Py3, [23]uint8{0xf3, 0x73, 06, Pe, 0xf3, Pe, 0x73, 06}}, - {APSLLW, yps, Py3, [23]uint8{0xf1, 0x71, 06, Pe, 0xf1, Pe, 0x71, 06}}, - {APSRAL, yps, Py3, [23]uint8{0xe2, 0x72, 04, Pe, 0xe2, Pe, 0x72, 04}}, - {APSRAW, yps, Py3, [23]uint8{0xe1, 0x71, 04, Pe, 0xe1, Pe, 0x71, 04}}, - {APSRLO, ypsdq, Pq, [23]uint8{0x73, 03}}, - {APSRLL, yps, Py3, [23]uint8{0xd2, 0x72, 02, Pe, 0xd2, Pe, 0x72, 02}}, - {APSRLQ, yps, Py3, [23]uint8{0xd3, 0x73, 02, Pe, 0xd3, Pe, 0x73, 02}}, - {APSRLW, yps, Py3, [23]uint8{0xd1, 0x71, 02, Pe, 0xd1, Pe, 0x71, 02}}, - {APSUBB, yxm, Pe, [23]uint8{0xf8}}, - {APSUBL, yxm, Pe, [23]uint8{0xfa}}, - {APSUBQ, yxm, Pe, [23]uint8{0xfb}}, - {APSUBSB, yxm, Pe, [23]uint8{0xe8}}, - {APSUBSW, yxm, Pe, [23]uint8{0xe9}}, - {APSUBUSB, yxm, Pe, [23]uint8{0xd8}}, - {APSUBUSW, yxm, Pe, [23]uint8{0xd9}}, - {APSUBW, yxm, Pe, [23]uint8{0xf9}}, - {APUNPCKHBW, ymm, Py1, [23]uint8{0x68, Pe, 0x68}}, - {APUNPCKHLQ, ymm, Py1, [23]uint8{0x6a, Pe, 0x6a}}, - {APUNPCKHQDQ, yxm, Pe, [23]uint8{0x6d}}, - {APUNPCKHWL, ymm, Py1, [23]uint8{0x69, Pe, 0x69}}, - {APUNPCKLBW, ymm, Py1, [23]uint8{0x60, Pe, 0x60}}, - {APUNPCKLLQ, ymm, Py1, [23]uint8{0x62, Pe, 0x62}}, - {APUNPCKLQDQ, yxm, Pe, [23]uint8{0x6c}}, - {APUNPCKLWL, ymm, Py1, [23]uint8{0x61, Pe, 0x61}}, - {APUSHAL, ynone, P32, [23]uint8{0x60}}, - {APUSHAW, ynone, Pe, [23]uint8{0x60}}, - {APUSHFL, ynone, P32, [23]uint8{0x9c}}, - {APUSHFQ, ynone, Py, [23]uint8{0x9c}}, - {APUSHFW, ynone, Pe, [23]uint8{0x9c}}, - {APUSHL, ypushl, P32, [23]uint8{0x50, 0xff, 06, 0x6a, 0x68}}, - {APUSHQ, ypushl, Py, [23]uint8{0x50, 0xff, 06, 0x6a, 0x68}}, - {APUSHW, ypushl, Pe, [23]uint8{0x50, 0xff, 06, 0x6a, 0x68}}, - {APXOR, ymm, Py1, [23]uint8{0xef, Pe, 0xef}}, - {AQUAD, ybyte, Px, [23]uint8{8}}, - {ARCLB, yshb, Pb, [23]uint8{0xd0, 02, 0xc0, 02, 0xd2, 02}}, - {ARCLL, yshl, Px, [23]uint8{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}}, - {ARCLQ, yshl, Pw, [23]uint8{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}}, - {ARCLW, yshl, Pe, [23]uint8{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}}, - {ARCPPS, yxm, Pm, [23]uint8{0x53}}, - {ARCPSS, yxm, Pf3, [23]uint8{0x53}}, - {ARCRB, yshb, Pb, [23]uint8{0xd0, 03, 0xc0, 03, 0xd2, 03}}, - {ARCRL, yshl, Px, [23]uint8{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}}, - {ARCRQ, yshl, Pw, [23]uint8{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}}, - {ARCRW, yshl, Pe, [23]uint8{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}}, - {AREP, ynone, Px, [23]uint8{0xf3}}, - {AREPN, ynone, Px, [23]uint8{0xf2}}, - {obj.ARET, ynone, Px, [23]uint8{0xc3}}, - {ARETFW, yret, Pe, [23]uint8{0xcb, 0xca}}, - {ARETFL, yret, Px, [23]uint8{0xcb, 0xca}}, - {ARETFQ, yret, Pw, [23]uint8{0xcb, 0xca}}, - {AROLB, yshb, Pb, [23]uint8{0xd0, 00, 0xc0, 00, 0xd2, 00}}, - {AROLL, yshl, Px, [23]uint8{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}}, - {AROLQ, yshl, Pw, [23]uint8{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}}, - {AROLW, yshl, Pe, [23]uint8{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}}, - {ARORB, yshb, Pb, [23]uint8{0xd0, 01, 0xc0, 01, 0xd2, 01}}, - {ARORL, yshl, Px, [23]uint8{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}}, - {ARORQ, yshl, Pw, [23]uint8{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}}, - {ARORW, yshl, Pe, [23]uint8{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}}, - {ARSQRTPS, yxm, Pm, [23]uint8{0x52}}, - {ARSQRTSS, yxm, Pf3, [23]uint8{0x52}}, - {ASAHF, ynone, Px1, [23]uint8{0x9e, 00, 0x86, 0xe0, 0x50, 0x9d}}, /* XCHGB AH,AL; PUSH AX; POPFL */ - {ASALB, yshb, Pb, [23]uint8{0xd0, 04, 0xc0, 04, 0xd2, 04}}, - {ASALL, yshl, Px, [23]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - {ASALQ, yshl, Pw, [23]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - {ASALW, yshl, Pe, [23]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - {ASARB, yshb, Pb, [23]uint8{0xd0, 07, 0xc0, 07, 0xd2, 07}}, - {ASARL, yshl, Px, [23]uint8{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}}, - {ASARQ, yshl, Pw, [23]uint8{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}}, - {ASARW, yshl, Pe, [23]uint8{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}}, - {ASBBB, yxorb, Pb, [23]uint8{0x1c, 0x80, 03, 0x18, 0x1a}}, - {ASBBL, yaddl, Px, [23]uint8{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}}, - {ASBBQ, yaddl, Pw, [23]uint8{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}}, - {ASBBW, yaddl, Pe, [23]uint8{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}}, - {ASCASB, ynone, Pb, [23]uint8{0xae}}, - {ASCASL, ynone, Px, [23]uint8{0xaf}}, - {ASCASQ, ynone, Pw, [23]uint8{0xaf}}, - {ASCASW, ynone, Pe, [23]uint8{0xaf}}, - {ASETCC, yscond, Pb, [23]uint8{0x0f, 0x93, 00}}, - {ASETCS, yscond, Pb, [23]uint8{0x0f, 0x92, 00}}, - {ASETEQ, yscond, Pb, [23]uint8{0x0f, 0x94, 00}}, - {ASETGE, yscond, Pb, [23]uint8{0x0f, 0x9d, 00}}, - {ASETGT, yscond, Pb, [23]uint8{0x0f, 0x9f, 00}}, - {ASETHI, yscond, Pb, [23]uint8{0x0f, 0x97, 00}}, - {ASETLE, yscond, Pb, [23]uint8{0x0f, 0x9e, 00}}, - {ASETLS, yscond, Pb, [23]uint8{0x0f, 0x96, 00}}, - {ASETLT, yscond, Pb, [23]uint8{0x0f, 0x9c, 00}}, - {ASETMI, yscond, Pb, [23]uint8{0x0f, 0x98, 00}}, - {ASETNE, yscond, Pb, [23]uint8{0x0f, 0x95, 00}}, - {ASETOC, yscond, Pb, [23]uint8{0x0f, 0x91, 00}}, - {ASETOS, yscond, Pb, [23]uint8{0x0f, 0x90, 00}}, - {ASETPC, yscond, Pb, [23]uint8{0x0f, 0x9b, 00}}, - {ASETPL, yscond, Pb, [23]uint8{0x0f, 0x99, 00}}, - {ASETPS, yscond, Pb, [23]uint8{0x0f, 0x9a, 00}}, - {ASHLB, yshb, Pb, [23]uint8{0xd0, 04, 0xc0, 04, 0xd2, 04}}, - {ASHLL, yshl, Px, [23]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - {ASHLQ, yshl, Pw, [23]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - {ASHLW, yshl, Pe, [23]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - {ASHRB, yshb, Pb, [23]uint8{0xd0, 05, 0xc0, 05, 0xd2, 05}}, - {ASHRL, yshl, Px, [23]uint8{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}}, - {ASHRQ, yshl, Pw, [23]uint8{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}}, - {ASHRW, yshl, Pe, [23]uint8{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}}, - {ASHUFPD, yxshuf, Pq, [23]uint8{0xc6, 00}}, - {ASHUFPS, yxshuf, Pm, [23]uint8{0xc6, 00}}, - {ASQRTPD, yxm, Pe, [23]uint8{0x51}}, - {ASQRTPS, yxm, Pm, [23]uint8{0x51}}, - {ASQRTSD, yxm, Pf2, [23]uint8{0x51}}, - {ASQRTSS, yxm, Pf3, [23]uint8{0x51}}, - {ASTC, ynone, Px, [23]uint8{0xf9}}, - {ASTD, ynone, Px, [23]uint8{0xfd}}, - {ASTI, ynone, Px, [23]uint8{0xfb}}, - {ASTMXCSR, ysvrs, Pm, [23]uint8{0xae, 03, 0xae, 03}}, - {ASTOSB, ynone, Pb, [23]uint8{0xaa}}, - {ASTOSL, ynone, Px, [23]uint8{0xab}}, - {ASTOSQ, ynone, Pw, [23]uint8{0xab}}, - {ASTOSW, ynone, Pe, [23]uint8{0xab}}, - {ASUBB, yxorb, Pb, [23]uint8{0x2c, 0x80, 05, 0x28, 0x2a}}, - {ASUBL, yaddl, Px, [23]uint8{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}}, - {ASUBPD, yxm, Pe, [23]uint8{0x5c}}, - {ASUBPS, yxm, Pm, [23]uint8{0x5c}}, - {ASUBQ, yaddl, Pw, [23]uint8{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}}, - {ASUBSD, yxm, Pf2, [23]uint8{0x5c}}, - {ASUBSS, yxm, Pf3, [23]uint8{0x5c}}, - {ASUBW, yaddl, Pe, [23]uint8{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}}, - {ASWAPGS, ynone, Pm, [23]uint8{0x01, 0xf8}}, - {ASYSCALL, ynone, Px, [23]uint8{0x0f, 0x05}}, /* fast syscall */ - {ATESTB, yxorb, Pb, [23]uint8{0xa8, 0xf6, 00, 0x84, 0x84}}, - {ATESTL, ytestl, Px, [23]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, - {ATESTQ, ytestl, Pw, [23]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, - {ATESTW, ytestl, Pe, [23]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, - {obj.ATEXT, ytext, Px, [23]uint8{}}, - {AUCOMISD, yxm, Pe, [23]uint8{0x2e}}, - {AUCOMISS, yxm, Pm, [23]uint8{0x2e}}, - {AUNPCKHPD, yxm, Pe, [23]uint8{0x15}}, - {AUNPCKHPS, yxm, Pm, [23]uint8{0x15}}, - {AUNPCKLPD, yxm, Pe, [23]uint8{0x14}}, - {AUNPCKLPS, yxm, Pm, [23]uint8{0x14}}, - {AVERR, ydivl, Pm, [23]uint8{0x00, 04}}, - {AVERW, ydivl, Pm, [23]uint8{0x00, 05}}, - {AWAIT, ynone, Px, [23]uint8{0x9b}}, - {AWORD, ybyte, Px, [23]uint8{2}}, - {AXCHGB, yml_mb, Pb, [23]uint8{0x86, 0x86}}, - {AXCHGL, yxchg, Px, [23]uint8{0x90, 0x90, 0x87, 0x87}}, - {AXCHGQ, yxchg, Pw, [23]uint8{0x90, 0x90, 0x87, 0x87}}, - {AXCHGW, yxchg, Pe, [23]uint8{0x90, 0x90, 0x87, 0x87}}, - {AXLAT, ynone, Px, [23]uint8{0xd7}}, - {AXORB, yxorb, Pb, [23]uint8{0x34, 0x80, 06, 0x30, 0x32}}, - {AXORL, yaddl, Px, [23]uint8{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}}, - {AXORPD, yxm, Pe, [23]uint8{0x57}}, - {AXORPS, yxm, Pm, [23]uint8{0x57}}, - {AXORQ, yaddl, Pw, [23]uint8{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}}, - {AXORW, yaddl, Pe, [23]uint8{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}}, - {AFMOVB, yfmvx, Px, [23]uint8{0xdf, 04}}, - {AFMOVBP, yfmvp, Px, [23]uint8{0xdf, 06}}, - {AFMOVD, yfmvd, Px, [23]uint8{0xdd, 00, 0xdd, 02, 0xd9, 00, 0xdd, 02}}, - {AFMOVDP, yfmvdp, Px, [23]uint8{0xdd, 03, 0xdd, 03}}, - {AFMOVF, yfmvf, Px, [23]uint8{0xd9, 00, 0xd9, 02}}, - {AFMOVFP, yfmvp, Px, [23]uint8{0xd9, 03}}, - {AFMOVL, yfmvf, Px, [23]uint8{0xdb, 00, 0xdb, 02}}, - {AFMOVLP, yfmvp, Px, [23]uint8{0xdb, 03}}, - {AFMOVV, yfmvx, Px, [23]uint8{0xdf, 05}}, - {AFMOVVP, yfmvp, Px, [23]uint8{0xdf, 07}}, - {AFMOVW, yfmvf, Px, [23]uint8{0xdf, 00, 0xdf, 02}}, - {AFMOVWP, yfmvp, Px, [23]uint8{0xdf, 03}}, - {AFMOVX, yfmvx, Px, [23]uint8{0xdb, 05}}, - {AFMOVXP, yfmvp, Px, [23]uint8{0xdb, 07}}, - {AFCMOVCC, yfcmv, Px, [23]uint8{0xdb, 00}}, - {AFCMOVCS, yfcmv, Px, [23]uint8{0xda, 00}}, - {AFCMOVEQ, yfcmv, Px, [23]uint8{0xda, 01}}, - {AFCMOVHI, yfcmv, Px, [23]uint8{0xdb, 02}}, - {AFCMOVLS, yfcmv, Px, [23]uint8{0xda, 02}}, - {AFCMOVNE, yfcmv, Px, [23]uint8{0xdb, 01}}, - {AFCMOVNU, yfcmv, Px, [23]uint8{0xdb, 03}}, - {AFCMOVUN, yfcmv, Px, [23]uint8{0xda, 03}}, - {AFCOMD, yfadd, Px, [23]uint8{0xdc, 02, 0xd8, 02, 0xdc, 02}}, /* botch */ - {AFCOMDP, yfadd, Px, [23]uint8{0xdc, 03, 0xd8, 03, 0xdc, 03}}, /* botch */ - {AFCOMDPP, ycompp, Px, [23]uint8{0xde, 03}}, - {AFCOMF, yfmvx, Px, [23]uint8{0xd8, 02}}, - {AFCOMFP, yfmvx, Px, [23]uint8{0xd8, 03}}, - {AFCOMI, yfmvx, Px, [23]uint8{0xdb, 06}}, - {AFCOMIP, yfmvx, Px, [23]uint8{0xdf, 06}}, - {AFCOML, yfmvx, Px, [23]uint8{0xda, 02}}, - {AFCOMLP, yfmvx, Px, [23]uint8{0xda, 03}}, - {AFCOMW, yfmvx, Px, [23]uint8{0xde, 02}}, - {AFCOMWP, yfmvx, Px, [23]uint8{0xde, 03}}, - {AFUCOM, ycompp, Px, [23]uint8{0xdd, 04}}, - {AFUCOMI, ycompp, Px, [23]uint8{0xdb, 05}}, - {AFUCOMIP, ycompp, Px, [23]uint8{0xdf, 05}}, - {AFUCOMP, ycompp, Px, [23]uint8{0xdd, 05}}, - {AFUCOMPP, ycompp, Px, [23]uint8{0xda, 13}}, - {AFADDDP, ycompp, Px, [23]uint8{0xde, 00}}, - {AFADDW, yfmvx, Px, [23]uint8{0xde, 00}}, - {AFADDL, yfmvx, Px, [23]uint8{0xda, 00}}, - {AFADDF, yfmvx, Px, [23]uint8{0xd8, 00}}, - {AFADDD, yfadd, Px, [23]uint8{0xdc, 00, 0xd8, 00, 0xdc, 00}}, - {AFMULDP, ycompp, Px, [23]uint8{0xde, 01}}, - {AFMULW, yfmvx, Px, [23]uint8{0xde, 01}}, - {AFMULL, yfmvx, Px, [23]uint8{0xda, 01}}, - {AFMULF, yfmvx, Px, [23]uint8{0xd8, 01}}, - {AFMULD, yfadd, Px, [23]uint8{0xdc, 01, 0xd8, 01, 0xdc, 01}}, - {AFSUBDP, ycompp, Px, [23]uint8{0xde, 05}}, - {AFSUBW, yfmvx, Px, [23]uint8{0xde, 04}}, - {AFSUBL, yfmvx, Px, [23]uint8{0xda, 04}}, - {AFSUBF, yfmvx, Px, [23]uint8{0xd8, 04}}, - {AFSUBD, yfadd, Px, [23]uint8{0xdc, 04, 0xd8, 04, 0xdc, 05}}, - {AFSUBRDP, ycompp, Px, [23]uint8{0xde, 04}}, - {AFSUBRW, yfmvx, Px, [23]uint8{0xde, 05}}, - {AFSUBRL, yfmvx, Px, [23]uint8{0xda, 05}}, - {AFSUBRF, yfmvx, Px, [23]uint8{0xd8, 05}}, - {AFSUBRD, yfadd, Px, [23]uint8{0xdc, 05, 0xd8, 05, 0xdc, 04}}, - {AFDIVDP, ycompp, Px, [23]uint8{0xde, 07}}, - {AFDIVW, yfmvx, Px, [23]uint8{0xde, 06}}, - {AFDIVL, yfmvx, Px, [23]uint8{0xda, 06}}, - {AFDIVF, yfmvx, Px, [23]uint8{0xd8, 06}}, - {AFDIVD, yfadd, Px, [23]uint8{0xdc, 06, 0xd8, 06, 0xdc, 07}}, - {AFDIVRDP, ycompp, Px, [23]uint8{0xde, 06}}, - {AFDIVRW, yfmvx, Px, [23]uint8{0xde, 07}}, - {AFDIVRL, yfmvx, Px, [23]uint8{0xda, 07}}, - {AFDIVRF, yfmvx, Px, [23]uint8{0xd8, 07}}, - {AFDIVRD, yfadd, Px, [23]uint8{0xdc, 07, 0xd8, 07, 0xdc, 06}}, - {AFXCHD, yfxch, Px, [23]uint8{0xd9, 01, 0xd9, 01}}, - {AFFREE, nil, 0, [23]uint8{}}, - {AFLDCW, ysvrs, Px, [23]uint8{0xd9, 05, 0xd9, 05}}, - {AFLDENV, ysvrs, Px, [23]uint8{0xd9, 04, 0xd9, 04}}, - {AFRSTOR, ysvrs, Px, [23]uint8{0xdd, 04, 0xdd, 04}}, - {AFSAVE, ysvrs, Px, [23]uint8{0xdd, 06, 0xdd, 06}}, - {AFSTCW, ysvrs, Px, [23]uint8{0xd9, 07, 0xd9, 07}}, - {AFSTENV, ysvrs, Px, [23]uint8{0xd9, 06, 0xd9, 06}}, - {AFSTSW, ystsw, Px, [23]uint8{0xdd, 07, 0xdf, 0xe0}}, - {AF2XM1, ynone, Px, [23]uint8{0xd9, 0xf0}}, - {AFABS, ynone, Px, [23]uint8{0xd9, 0xe1}}, - {AFCHS, ynone, Px, [23]uint8{0xd9, 0xe0}}, - {AFCLEX, ynone, Px, [23]uint8{0xdb, 0xe2}}, - {AFCOS, ynone, Px, [23]uint8{0xd9, 0xff}}, - {AFDECSTP, ynone, Px, [23]uint8{0xd9, 0xf6}}, - {AFINCSTP, ynone, Px, [23]uint8{0xd9, 0xf7}}, - {AFINIT, ynone, Px, [23]uint8{0xdb, 0xe3}}, - {AFLD1, ynone, Px, [23]uint8{0xd9, 0xe8}}, - {AFLDL2E, ynone, Px, [23]uint8{0xd9, 0xea}}, - {AFLDL2T, ynone, Px, [23]uint8{0xd9, 0xe9}}, - {AFLDLG2, ynone, Px, [23]uint8{0xd9, 0xec}}, - {AFLDLN2, ynone, Px, [23]uint8{0xd9, 0xed}}, - {AFLDPI, ynone, Px, [23]uint8{0xd9, 0xeb}}, - {AFLDZ, ynone, Px, [23]uint8{0xd9, 0xee}}, - {AFNOP, ynone, Px, [23]uint8{0xd9, 0xd0}}, - {AFPATAN, ynone, Px, [23]uint8{0xd9, 0xf3}}, - {AFPREM, ynone, Px, [23]uint8{0xd9, 0xf8}}, - {AFPREM1, ynone, Px, [23]uint8{0xd9, 0xf5}}, - {AFPTAN, ynone, Px, [23]uint8{0xd9, 0xf2}}, - {AFRNDINT, ynone, Px, [23]uint8{0xd9, 0xfc}}, - {AFSCALE, ynone, Px, [23]uint8{0xd9, 0xfd}}, - {AFSIN, ynone, Px, [23]uint8{0xd9, 0xfe}}, - {AFSINCOS, ynone, Px, [23]uint8{0xd9, 0xfb}}, - {AFSQRT, ynone, Px, [23]uint8{0xd9, 0xfa}}, - {AFTST, ynone, Px, [23]uint8{0xd9, 0xe4}}, - {AFXAM, ynone, Px, [23]uint8{0xd9, 0xe5}}, - {AFXTRACT, ynone, Px, [23]uint8{0xd9, 0xf4}}, - {AFYL2X, ynone, Px, [23]uint8{0xd9, 0xf1}}, - {AFYL2XP1, ynone, Px, [23]uint8{0xd9, 0xf9}}, - {ACMPXCHGB, yrb_mb, Pb, [23]uint8{0x0f, 0xb0}}, - {ACMPXCHGL, yrl_ml, Px, [23]uint8{0x0f, 0xb1}}, - {ACMPXCHGW, yrl_ml, Pe, [23]uint8{0x0f, 0xb1}}, - {ACMPXCHGQ, yrl_ml, Pw, [23]uint8{0x0f, 0xb1}}, - {ACMPXCHG8B, yscond, Pm, [23]uint8{0xc7, 01}}, - {AINVD, ynone, Pm, [23]uint8{0x08}}, - {AINVLPG, ydivb, Pm, [23]uint8{0x01, 07}}, - {ALFENCE, ynone, Pm, [23]uint8{0xae, 0xe8}}, - {AMFENCE, ynone, Pm, [23]uint8{0xae, 0xf0}}, - {AMOVNTIL, yrl_ml, Pm, [23]uint8{0xc3}}, - {AMOVNTIQ, yrl_ml, Pw, [23]uint8{0x0f, 0xc3}}, - {ARDMSR, ynone, Pm, [23]uint8{0x32}}, - {ARDPMC, ynone, Pm, [23]uint8{0x33}}, - {ARDTSC, ynone, Pm, [23]uint8{0x31}}, - {ARSM, ynone, Pm, [23]uint8{0xaa}}, - {ASFENCE, ynone, Pm, [23]uint8{0xae, 0xf8}}, - {ASYSRET, ynone, Pm, [23]uint8{0x07}}, - {AWBINVD, ynone, Pm, [23]uint8{0x09}}, - {AWRMSR, ynone, Pm, [23]uint8{0x30}}, - {AXADDB, yrb_mb, Pb, [23]uint8{0x0f, 0xc0}}, - {AXADDL, yrl_ml, Px, [23]uint8{0x0f, 0xc1}}, - {AXADDQ, yrl_ml, Pw, [23]uint8{0x0f, 0xc1}}, - {AXADDW, yrl_ml, Pe, [23]uint8{0x0f, 0xc1}}, - {ACRC32B, ycrc32l, Px, [23]uint8{0xf2, 0x0f, 0x38, 0xf0, 0}}, - {ACRC32Q, ycrc32l, Pw, [23]uint8{0xf2, 0x0f, 0x38, 0xf1, 0}}, - {APREFETCHT0, yprefetch, Pm, [23]uint8{0x18, 01}}, - {APREFETCHT1, yprefetch, Pm, [23]uint8{0x18, 02}}, - {APREFETCHT2, yprefetch, Pm, [23]uint8{0x18, 03}}, - {APREFETCHNTA, yprefetch, Pm, [23]uint8{0x18, 00}}, - {AMOVQL, yrl_ml, Px, [23]uint8{0x89}}, - {obj.AUNDEF, ynone, Px, [23]uint8{0x0f, 0x0b}}, - {AAESENC, yaes, Pq, [23]uint8{0x38, 0xdc, 0}}, - {AAESENCLAST, yaes, Pq, [23]uint8{0x38, 0xdd, 0}}, - {AAESDEC, yaes, Pq, [23]uint8{0x38, 0xde, 0}}, - {AAESDECLAST, yaes, Pq, [23]uint8{0x38, 0xdf, 0}}, - {AAESIMC, yaes, Pq, [23]uint8{0x38, 0xdb, 0}}, - {AAESKEYGENASSIST, yxshuf, Pq, [23]uint8{0x3a, 0xdf, 0}}, - {AROUNDPD, yxshuf, Pq, [23]uint8{0x3a, 0x09, 0}}, - {AROUNDPS, yxshuf, Pq, [23]uint8{0x3a, 0x08, 0}}, - {AROUNDSD, yxshuf, Pq, [23]uint8{0x3a, 0x0b, 0}}, - {AROUNDSS, yxshuf, Pq, [23]uint8{0x3a, 0x0a, 0}}, - {APSHUFD, yxshuf, Pq, [23]uint8{0x70, 0}}, - {APCLMULQDQ, yxshuf, Pq, [23]uint8{0x3a, 0x44, 0}}, - {APCMPESTRI, yxshuf, Pq, [23]uint8{0x3a, 0x61, 0}}, - {AMOVDDUP, yxm, Pf2, [23]uint8{0x12}}, - {AMOVSHDUP, yxm, Pf3, [23]uint8{0x16}}, - {AMOVSLDUP, yxm, Pf3, [23]uint8{0x12}}, - - {AANDNL, yvex_r3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF2}}, - {AANDNQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF2}}, - {ABEXTRL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF7}}, - {ABEXTRQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF7}}, - {ABZHIL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF5}}, - {ABZHIQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF5}}, - {AMULXL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF6}}, - {AMULXQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF6}}, - {APDEPL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF5}}, - {APDEPQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF5}}, - {APEXTL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W0, 0xF5}}, - {APEXTQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W1, 0xF5}}, - {ASARXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W0, 0xF7}}, - {ASARXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W1, 0xF7}}, - {ASHLXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_66_0F38_W0, 0xF7}}, - {ASHLXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_66_0F38_W1, 0xF7}}, - {ASHRXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF7}}, - {ASHRXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF7}}, - - {AVZEROUPPER, ynone, Px, [23]uint8{0xc5, 0xf8, 0x77}}, - {AVMOVDQU, yvex_vmovdqa, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x6F, VEX_128_F3_0F_WIG, 0x7F, VEX_256_F3_0F_WIG, 0x6F, VEX_256_F3_0F_WIG, 0x7F}}, - {AVMOVDQA, yvex_vmovdqa, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x6F, VEX_128_66_0F_WIG, 0x7F, VEX_256_66_0F_WIG, 0x6F, VEX_256_66_0F_WIG, 0x7F}}, - {AVMOVNTDQ, yvex_vmovntdq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xE7, VEX_256_66_0F_WIG, 0xE7}}, - {AVPCMPEQB, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x74, VEX_256_66_0F_WIG, 0x74}}, - {AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xEF, VEX_256_66_0F_WIG, 0xEF}}, - {AVPMOVMSKB, yvex_xyr2, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xD7, VEX_256_66_0F_WIG, 0xD7}}, - {AVPAND, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xDB, VEX_256_66_0F_WIG, 0xDB}}, - {AVPBROADCASTB, yvex_vpbroadcast, Pvex, [23]uint8{VEX_128_66_0F38_W0, 0x78, VEX_256_66_0F38_W0, 0x78}}, - {AVPTEST, yvex_xy2, Pvex, [23]uint8{VEX_128_66_0F38_WIG, 0x17, VEX_256_66_0F38_WIG, 0x17}}, - {AVPSHUFB, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F38_WIG, 0x00, VEX_256_66_0F38_WIG, 0x00}}, - {AVPSHUFD, yvex_xyi3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x70, VEX_256_66_0F_WIG, 0x70, VEX_128_66_0F_WIG, 0x70, VEX_256_66_0F_WIG, 0x70}}, - {AVPOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xeb, VEX_256_66_0F_WIG, 0xeb}}, - {AVPADDQ, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xd4, VEX_256_66_0F_WIG, 0xd4}}, - {AVPADDD, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xfe, VEX_256_66_0F_WIG, 0xfe}}, - {AVPSLLD, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x72, 0xf0, VEX_256_66_0F_WIG, 0x72, 0xf0, VEX_128_66_0F_WIG, 0xf2, VEX_256_66_0F_WIG, 0xf2}}, - {AVPSLLQ, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xf0, VEX_256_66_0F_WIG, 0x73, 0xf0, VEX_128_66_0F_WIG, 0xf3, VEX_256_66_0F_WIG, 0xf3}}, - {AVPSRLD, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x72, 0xd0, VEX_256_66_0F_WIG, 0x72, 0xd0, VEX_128_66_0F_WIG, 0xd2, VEX_256_66_0F_WIG, 0xd2}}, - {AVPSRLQ, yvex_shift, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xd0, VEX_256_66_0F_WIG, 0x73, 0xd0, VEX_128_66_0F_WIG, 0xd3, VEX_256_66_0F_WIG, 0xd3}}, - {AVPSRLDQ, yvex_shift_dq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xd8, VEX_256_66_0F_WIG, 0x73, 0xd8}}, - {AVPSLLDQ, yvex_shift_dq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x73, 0xf8, VEX_256_66_0F_WIG, 0x73, 0xf8}}, - {AVPERM2F128, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_W0, 0x06}}, - {AVPALIGNR, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x0f}}, - {AVPBLENDD, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x02}}, - {AVINSERTI128, yvex_xyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x38}}, - {AVPERM2I128, yvex_yyi4, Pvex, [23]uint8{VEX_256_66_0F3A_WIG, 0x46}}, - {ARORXL, yvex_ri3, Pvex, [23]uint8{VEX_LZ_F2_0F3A_W0, 0xf0}}, - {ARORXQ, yvex_ri3, Pvex, [23]uint8{VEX_LZ_F2_0F3A_W1, 0xf0}}, - {AVBROADCASTSD, yvex_vpbroadcast_sd, Pvex, [23]uint8{VEX_256_66_0F38_W0, 0x19}}, - {AVBROADCASTSS, yvex_vpbroadcast, Pvex, [23]uint8{VEX_128_66_0F38_W0, 0x18, VEX_256_66_0F38_W0, 0x18}}, - {AVMOVDDUP, yvex_xy2, Pvex, [23]uint8{VEX_128_F2_0F_WIG, 0x12, VEX_256_F2_0F_WIG, 0x12}}, - {AVMOVSHDUP, yvex_xy2, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x16, VEX_256_F3_0F_WIG, 0x16}}, - {AVMOVSLDUP, yvex_xy2, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x12, VEX_256_F3_0F_WIG, 0x12}}, - - {AXACQUIRE, ynone, Px, [23]uint8{0xf2}}, - {AXRELEASE, ynone, Px, [23]uint8{0xf3}}, - {AXBEGIN, yxbegin, Px, [23]uint8{0xc7, 0xf8}}, - {AXABORT, yxabort, Px, [23]uint8{0xc6, 0xf8}}, - {AXEND, ynone, Px, [23]uint8{0x0f, 01, 0xd5}}, - {AXTEST, ynone, Px, [23]uint8{0x0f, 01, 0xd6}}, - {AXGETBV, ynone, Pm, [23]uint8{01, 0xd0}}, - {obj.AUSEFIELD, ynop, Px, [23]uint8{0, 0}}, - {obj.ATYPE, nil, 0, [23]uint8{}}, - {obj.AFUNCDATA, yfuncdata, Px, [23]uint8{0, 0}}, - {obj.APCDATA, ypcdata, Px, [23]uint8{0, 0}}, - {obj.AVARDEF, nil, 0, [23]uint8{}}, - {obj.AVARKILL, nil, 0, [23]uint8{}}, - {obj.ADUFFCOPY, yduff, Px, [23]uint8{0xe8}}, - {obj.ADUFFZERO, yduff, Px, [23]uint8{0xe8}}, - {obj.AEND, nil, 0, [23]uint8{}}, - {0, nil, 0, [23]uint8{}}, -} - -var opindex [(ALAST + 1) & obj.AMask]*Optab - -// isextern reports whether s describes an external symbol that must avoid pc-relative addressing. -// This happens on systems like Solaris that call .so functions instead of system calls. -// It does not seem to be necessary for any other systems. This is probably working -// around a Solaris-specific bug that should be fixed differently, but we don't know -// what that bug is. And this does fix it. -func isextern(s *obj.LSym) bool { - // All the Solaris dynamic imports from libc.so begin with "libc_". - return strings.HasPrefix(s.Name, "libc_") -} - -// single-instruction no-ops of various lengths. -// constructed by hand and disassembled with gdb to verify. -// see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion. -var nop = [][16]uint8{ - {0x90}, - {0x66, 0x90}, - {0x0F, 0x1F, 0x00}, - {0x0F, 0x1F, 0x40, 0x00}, - {0x0F, 0x1F, 0x44, 0x00, 0x00}, - {0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00}, - {0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00}, - {0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, -} - -// Native Client rejects the repeated 0x66 prefix. -// {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, -func fillnop(p []byte, n int) { - var m int - - for n > 0 { - m = n - if m > len(nop) { - m = len(nop) - } - copy(p[:m], nop[m-1][:m]) - p = p[m:] - n -= m - } -} - -func naclpad(ctxt *obj.Link, s *obj.LSym, c int32, pad int32) int32 { - s.Grow(int64(c) + int64(pad)) - fillnop(s.P[c:], int(pad)) - return c + pad -} - -func spadjop(ctxt *obj.Link, p *obj.Prog, l, q obj.As) obj.As { - if p.Mode != 64 || ctxt.Arch.PtrSize == 4 { - return l - } - return q -} - -func span6(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - if s.P != nil { - return - } - - if ycover[0] == 0 { - instinit() - } - - for p := ctxt.Cursym.Text; p != nil; p = p.Link { - if p.To.Type == obj.TYPE_BRANCH { - if p.Pcond == nil { - p.Pcond = p - } - } - if p.As == AADJSP { - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SP - v := int32(-p.From.Offset) - p.From.Offset = int64(v) - p.As = spadjop(ctxt, p, AADDL, AADDQ) - if v < 0 { - p.As = spadjop(ctxt, p, ASUBL, ASUBQ) - v = -v - p.From.Offset = int64(v) - } - - if v == 0 { - p.As = obj.ANOP - } - } - } - - var q *obj.Prog - var count int64 // rough count of number of instructions - for p := s.Text; p != nil; p = p.Link { - count++ - p.Back = 2 // use short branches first time through - q = p.Pcond - if q != nil && (q.Back&2 != 0) { - p.Back |= 1 // backward jump - q.Back |= 4 // loop head - } - - if p.As == AADJSP { - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SP - v := int32(-p.From.Offset) - p.From.Offset = int64(v) - p.As = spadjop(ctxt, p, AADDL, AADDQ) - if v < 0 { - p.As = spadjop(ctxt, p, ASUBL, ASUBQ) - v = -v - p.From.Offset = int64(v) - } - - if v == 0 { - p.As = obj.ANOP - } - } - } - s.GrowCap(count * 5) // preallocate roughly 5 bytes per instruction - - n := 0 - var c int32 - errors := ctxt.Errors - var deferreturn *obj.LSym - if ctxt.Headtype == obj.Hnacl { - deferreturn = obj.Linklookup(ctxt, "runtime.deferreturn", 0) - } - for { - loop := int32(0) - for i := range s.R { - s.R[i] = obj.Reloc{} - } - s.R = s.R[:0] - s.P = s.P[:0] - c = 0 - for p := s.Text; p != nil; p = p.Link { - if ctxt.Headtype == obj.Hnacl && p.Isize > 0 { - - // pad everything to avoid crossing 32-byte boundary - if c>>5 != (c+int32(p.Isize)-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) - } - - // pad call deferreturn to start at 32-byte boundary - // so that subtracting 5 in jmpdefer will jump back - // to that boundary and rerun the call. - if p.As == obj.ACALL && p.To.Sym == deferreturn { - c = naclpad(ctxt, s, c, -c&31) - } - - // pad call to end at 32-byte boundary - if p.As == obj.ACALL { - c = naclpad(ctxt, s, c, -(c+int32(p.Isize))&31) - } - - // the linker treats REP and STOSQ as different instructions - // but in fact the REP is a prefix on the STOSQ. - // make sure REP has room for 2 more bytes, so that - // padding will not be inserted before the next instruction. - if (p.As == AREP || p.As == AREPN) && c>>5 != (c+3-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) - } - - // same for LOCK. - // various instructions follow; the longest is 4 bytes. - // give ourselves 8 bytes so as to avoid surprises. - if p.As == ALOCK && c>>5 != (c+8-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) - } - } - - if (p.Back&4 != 0) && c&(LoopAlign-1) != 0 { - // pad with NOPs - v := -c & (LoopAlign - 1) - - if v <= MaxLoopPad { - s.Grow(int64(c) + int64(v)) - fillnop(s.P[c:], int(v)) - c += v - } - } - - p.Pc = int64(c) - - // process forward jumps to p - for q = p.Rel; q != nil; q = q.Forwd { - v := int32(p.Pc - (q.Pc + int64(q.Isize))) - if q.Back&2 != 0 { // short - if v > 127 { - loop++ - q.Back ^= 2 - } - - if q.As == AJCXZL || q.As == AXBEGIN { - s.P[q.Pc+2] = byte(v) - } else { - s.P[q.Pc+1] = byte(v) - } - } else { - binary.LittleEndian.PutUint32(s.P[q.Pc+int64(q.Isize)-4:], uint32(v)) - } - } - - p.Rel = nil - - p.Pc = int64(c) - asmins(ctxt, p) - m := ctxt.AsmBuf.Len() - if int(p.Isize) != m { - p.Isize = uint8(m) - loop++ - } - - s.Grow(p.Pc + int64(m)) - copy(s.P[p.Pc:], ctxt.AsmBuf.Bytes()) - c += int32(m) - } - - n++ - if n > 20 { - ctxt.Diag("span must be looping") - log.Fatalf("loop") - } - if loop == 0 { - break - } - if ctxt.Errors > errors { - return - } - } - - if ctxt.Headtype == obj.Hnacl { - c = naclpad(ctxt, s, c, -c&31) - } - - s.Size = int64(c) - - if false { /* debug['a'] > 1 */ - fmt.Printf("span1 %s %d (%d tries)\n %.6x", s.Name, s.Size, n, 0) - var i int - for i = 0; i < len(s.P); i++ { - fmt.Printf(" %.2x", s.P[i]) - if i%16 == 15 { - fmt.Printf("\n %.6x", uint(i+1)) - } - } - - if i%16 != 0 { - fmt.Printf("\n") - } - - for i := 0; i < len(s.R); i++ { - r := &s.R[i] - fmt.Printf(" rel %#.4x/%d %s%+d\n", uint32(r.Off), r.Siz, r.Sym.Name, r.Add) - } - } -} - -func instinit() { - for i := 1; optab[i].as != 0; i++ { - c := optab[i].as - if opindex[c&obj.AMask] != nil { - log.Fatalf("phase error in optab: %d (%v)", i, c) - } - opindex[c&obj.AMask] = &optab[i] - } - - for i := 0; i < Ymax; i++ { - ycover[i*Ymax+i] = 1 - } - - ycover[Yi0*Ymax+Yi8] = 1 - ycover[Yi1*Ymax+Yi8] = 1 - ycover[Yu7*Ymax+Yi8] = 1 - - ycover[Yi0*Ymax+Yu7] = 1 - ycover[Yi1*Ymax+Yu7] = 1 - - ycover[Yi0*Ymax+Yu8] = 1 - ycover[Yi1*Ymax+Yu8] = 1 - ycover[Yu7*Ymax+Yu8] = 1 - - ycover[Yi0*Ymax+Ys32] = 1 - ycover[Yi1*Ymax+Ys32] = 1 - ycover[Yu7*Ymax+Ys32] = 1 - ycover[Yu8*Ymax+Ys32] = 1 - ycover[Yi8*Ymax+Ys32] = 1 - - ycover[Yi0*Ymax+Yi32] = 1 - ycover[Yi1*Ymax+Yi32] = 1 - ycover[Yu7*Ymax+Yi32] = 1 - ycover[Yu8*Ymax+Yi32] = 1 - ycover[Yi8*Ymax+Yi32] = 1 - ycover[Ys32*Ymax+Yi32] = 1 - - ycover[Yi0*Ymax+Yi64] = 1 - ycover[Yi1*Ymax+Yi64] = 1 - ycover[Yu7*Ymax+Yi64] = 1 - ycover[Yu8*Ymax+Yi64] = 1 - ycover[Yi8*Ymax+Yi64] = 1 - ycover[Ys32*Ymax+Yi64] = 1 - ycover[Yi32*Ymax+Yi64] = 1 - - ycover[Yal*Ymax+Yrb] = 1 - ycover[Ycl*Ymax+Yrb] = 1 - ycover[Yax*Ymax+Yrb] = 1 - ycover[Ycx*Ymax+Yrb] = 1 - ycover[Yrx*Ymax+Yrb] = 1 - ycover[Yrl*Ymax+Yrb] = 1 // but not Yrl32 - - ycover[Ycl*Ymax+Ycx] = 1 - - ycover[Yax*Ymax+Yrx] = 1 - ycover[Ycx*Ymax+Yrx] = 1 - - ycover[Yax*Ymax+Yrl] = 1 - ycover[Ycx*Ymax+Yrl] = 1 - ycover[Yrx*Ymax+Yrl] = 1 - ycover[Yrl32*Ymax+Yrl] = 1 - - ycover[Yf0*Ymax+Yrf] = 1 - - ycover[Yal*Ymax+Ymb] = 1 - ycover[Ycl*Ymax+Ymb] = 1 - ycover[Yax*Ymax+Ymb] = 1 - ycover[Ycx*Ymax+Ymb] = 1 - ycover[Yrx*Ymax+Ymb] = 1 - ycover[Yrb*Ymax+Ymb] = 1 - ycover[Yrl*Ymax+Ymb] = 1 // but not Yrl32 - ycover[Ym*Ymax+Ymb] = 1 - - ycover[Yax*Ymax+Yml] = 1 - ycover[Ycx*Ymax+Yml] = 1 - ycover[Yrx*Ymax+Yml] = 1 - ycover[Yrl*Ymax+Yml] = 1 - ycover[Yrl32*Ymax+Yml] = 1 - ycover[Ym*Ymax+Yml] = 1 - - ycover[Yax*Ymax+Ymm] = 1 - ycover[Ycx*Ymax+Ymm] = 1 - ycover[Yrx*Ymax+Ymm] = 1 - ycover[Yrl*Ymax+Ymm] = 1 - ycover[Yrl32*Ymax+Ymm] = 1 - ycover[Ym*Ymax+Ymm] = 1 - ycover[Ymr*Ymax+Ymm] = 1 - - ycover[Ym*Ymax+Yxm] = 1 - ycover[Yxr*Ymax+Yxm] = 1 - - ycover[Ym*Ymax+Yym] = 1 - ycover[Yyr*Ymax+Yym] = 1 - - for i := 0; i < MAXREG; i++ { - reg[i] = -1 - if i >= REG_AL && i <= REG_R15B { - reg[i] = (i - REG_AL) & 7 - if i >= REG_SPB && i <= REG_DIB { - regrex[i] = 0x40 - } - if i >= REG_R8B && i <= REG_R15B { - regrex[i] = Rxr | Rxx | Rxb - } - } - - if i >= REG_AH && i <= REG_BH { - reg[i] = 4 + ((i - REG_AH) & 7) - } - if i >= REG_AX && i <= REG_R15 { - reg[i] = (i - REG_AX) & 7 - if i >= REG_R8 { - regrex[i] = Rxr | Rxx | Rxb - } - } - - if i >= REG_F0 && i <= REG_F0+7 { - reg[i] = (i - REG_F0) & 7 - } - if i >= REG_M0 && i <= REG_M0+7 { - reg[i] = (i - REG_M0) & 7 - } - if i >= REG_X0 && i <= REG_X0+15 { - reg[i] = (i - REG_X0) & 7 - if i >= REG_X0+8 { - regrex[i] = Rxr | Rxx | Rxb - } - } - if i >= REG_Y0 && i <= REG_Y0+15 { - reg[i] = (i - REG_Y0) & 7 - if i >= REG_Y0+8 { - regrex[i] = Rxr | Rxx | Rxb - } - } - - if i >= REG_CR+8 && i <= REG_CR+15 { - regrex[i] = Rxr - } - } -} - -var isAndroid = (obj.GOOS == "android") - -func prefixof(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { - if a.Reg < REG_CS && a.Index < REG_CS { // fast path - return 0 - } - if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE { - switch a.Reg { - case REG_CS: - return 0x2e - - case REG_DS: - return 0x3e - - case REG_ES: - return 0x26 - - case REG_FS: - return 0x64 - - case REG_GS: - return 0x65 - - case REG_TLS: - // NOTE: Systems listed here should be only systems that - // support direct TLS references like 8(TLS) implemented as - // direct references from FS or GS. Systems that require - // the initial-exec model, where you load the TLS base into - // a register and then index from that register, do not reach - // this code and should not be listed. - if p.Mode == 32 { - switch ctxt.Headtype { - default: - if isAndroid { - return 0x65 // GS - } - log.Fatalf("unknown TLS base register for %v", ctxt.Headtype) - - case obj.Hdarwin, - obj.Hdragonfly, - obj.Hfreebsd, - obj.Hnetbsd, - obj.Hopenbsd: - return 0x65 // GS - } - } - - switch ctxt.Headtype { - default: - log.Fatalf("unknown TLS base register for %v", ctxt.Headtype) - - case obj.Hlinux: - if isAndroid { - return 0x64 // FS - } - - if ctxt.Flag_shared { - log.Fatalf("unknown TLS base register for linux with -shared") - } else { - return 0x64 // FS - } - - case obj.Hdragonfly, - obj.Hfreebsd, - obj.Hnetbsd, - obj.Hopenbsd, - obj.Hsolaris: - return 0x64 // FS - - case obj.Hdarwin: - return 0x65 // GS - } - } - } - - if p.Mode == 32 { - if a.Index == REG_TLS && ctxt.Flag_shared { - // When building for inclusion into a shared library, an instruction of the form - // MOVL 0(CX)(TLS*1), AX - // becomes - // mov %gs:(%ecx), %eax - // which assumes that the correct TLS offset has been loaded into %ecx (today - // there is only one TLS variable -- g -- so this is OK). When not building for - // a shared library the instruction it becomes - // mov 0x0(%ecx), $eax - // and a R_TLS_LE relocation, and so does not require a prefix. - if a.Offset != 0 { - ctxt.Diag("cannot handle non-0 offsets to TLS") - } - return 0x65 // GS - } - return 0 - } - - switch a.Index { - case REG_CS: - return 0x2e - - case REG_DS: - return 0x3e - - case REG_ES: - return 0x26 - - case REG_TLS: - if ctxt.Flag_shared { - // When building for inclusion into a shared library, an instruction of the form - // MOV 0(CX)(TLS*1), AX - // becomes - // mov %fs:(%rcx), %rax - // which assumes that the correct TLS offset has been loaded into %rcx (today - // there is only one TLS variable -- g -- so this is OK). When not building for - // a shared library the instruction does not require a prefix. - if a.Offset != 0 { - log.Fatalf("cannot handle non-0 offsets to TLS") - } - return 0x64 - } - - case REG_FS: - return 0x64 - - case REG_GS: - return 0x65 - } - - return 0 -} - -func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return Ynone - - case obj.TYPE_BRANCH: - return Ybr - - case obj.TYPE_INDIR: - if a.Name != obj.NAME_NONE && a.Reg == REG_NONE && a.Index == REG_NONE && a.Scale == 0 { - return Yindir - } - return Yxxx - - case obj.TYPE_MEM: - if a.Index == REG_SP { - // Can't use SP as the index register - return Yxxx - } - if ctxt.Asmode == 64 { - switch a.Name { - case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF: - // Global variables can't use index registers and their - // base register is %rip (%rip is encoded as REG_NONE). - if a.Reg != REG_NONE || a.Index != REG_NONE || a.Scale != 0 { - return Yxxx - } - case obj.NAME_AUTO, obj.NAME_PARAM: - // These names must have a base of SP. The old compiler - // uses 0 for the base register. SSA uses REG_SP. - if a.Reg != REG_SP && a.Reg != 0 { - return Yxxx - } - case obj.NAME_NONE: - // everything is ok - default: - // unknown name - return Yxxx - } - } - return Ym - - case obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_GOTREF: - ctxt.Diag("unexpected TYPE_ADDR with NAME_GOTREF") - return Yxxx - - case obj.NAME_EXTERN, - obj.NAME_STATIC: - if a.Sym != nil && isextern(a.Sym) || (p.Mode == 32 && !ctxt.Flag_shared) { - return Yi32 - } - return Yiauto // use pc-relative addressing - - case obj.NAME_AUTO, - obj.NAME_PARAM: - return Yiauto - } - - // TODO(rsc): DUFFZERO/DUFFCOPY encoding forgot to set a->index - // and got Yi32 in an earlier version of this code. - // Keep doing that until we fix yduff etc. - if a.Sym != nil && strings.HasPrefix(a.Sym.Name, "runtime.duff") { - return Yi32 - } - - if a.Sym != nil || a.Name != obj.NAME_NONE { - ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a)) - } - fallthrough - - // fall through - - case obj.TYPE_CONST: - if a.Sym != nil { - ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, a)) - } - - v := a.Offset - if p.Mode == 32 { - v = int64(int32(v)) - } - if v == 0 { - if p.Mark&PRESERVEFLAGS != 0 { - // If PRESERVEFLAGS is set, avoid MOV $0, AX turning into XOR AX, AX. - return Yu7 - } - return Yi0 - } - if v == 1 { - return Yi1 - } - if v >= 0 && v <= 127 { - return Yu7 - } - if v >= 0 && v <= 255 { - return Yu8 - } - if v >= -128 && v <= 127 { - return Yi8 - } - if p.Mode == 32 { - return Yi32 - } - l := int32(v) - if int64(l) == v { - return Ys32 /* can sign extend */ - } - if v>>32 == 0 { - return Yi32 /* unsigned */ - } - return Yi64 - - case obj.TYPE_TEXTSIZE: - return Ytextsize - } - - if a.Type != obj.TYPE_REG { - ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, a)) - return Yxxx - } - - switch a.Reg { - case REG_AL: - return Yal - - case REG_AX: - return Yax - - /* - case REG_SPB: - */ - case REG_BPB, - REG_SIB, - REG_DIB, - REG_R8B, - REG_R9B, - REG_R10B, - REG_R11B, - REG_R12B, - REG_R13B, - REG_R14B, - REG_R15B: - if ctxt.Asmode != 64 { - return Yxxx - } - fallthrough - - case REG_DL, - REG_BL, - REG_AH, - REG_CH, - REG_DH, - REG_BH: - return Yrb - - case REG_CL: - return Ycl - - case REG_CX: - return Ycx - - case REG_DX, REG_BX: - return Yrx - - case REG_R8, /* not really Yrl */ - REG_R9, - REG_R10, - REG_R11, - REG_R12, - REG_R13, - REG_R14, - REG_R15: - if ctxt.Asmode != 64 { - return Yxxx - } - fallthrough - - case REG_SP, REG_BP, REG_SI, REG_DI: - if p.Mode == 32 { - return Yrl32 - } - return Yrl - - case REG_F0 + 0: - return Yf0 - - case REG_F0 + 1, - REG_F0 + 2, - REG_F0 + 3, - REG_F0 + 4, - REG_F0 + 5, - REG_F0 + 6, - REG_F0 + 7: - return Yrf - - case REG_M0 + 0, - REG_M0 + 1, - REG_M0 + 2, - REG_M0 + 3, - REG_M0 + 4, - REG_M0 + 5, - REG_M0 + 6, - REG_M0 + 7: - return Ymr - - case REG_X0 + 0, - REG_X0 + 1, - REG_X0 + 2, - REG_X0 + 3, - REG_X0 + 4, - REG_X0 + 5, - REG_X0 + 6, - REG_X0 + 7, - REG_X0 + 8, - REG_X0 + 9, - REG_X0 + 10, - REG_X0 + 11, - REG_X0 + 12, - REG_X0 + 13, - REG_X0 + 14, - REG_X0 + 15: - return Yxr - - case REG_Y0 + 0, - REG_Y0 + 1, - REG_Y0 + 2, - REG_Y0 + 3, - REG_Y0 + 4, - REG_Y0 + 5, - REG_Y0 + 6, - REG_Y0 + 7, - REG_Y0 + 8, - REG_Y0 + 9, - REG_Y0 + 10, - REG_Y0 + 11, - REG_Y0 + 12, - REG_Y0 + 13, - REG_Y0 + 14, - REG_Y0 + 15: - return Yyr - - case REG_CS: - return Ycs - case REG_SS: - return Yss - case REG_DS: - return Yds - case REG_ES: - return Yes - case REG_FS: - return Yfs - case REG_GS: - return Ygs - case REG_TLS: - return Ytls - - case REG_GDTR: - return Ygdtr - case REG_IDTR: - return Yidtr - case REG_LDTR: - return Yldtr - case REG_MSW: - return Ymsw - case REG_TASK: - return Ytask - - case REG_CR + 0: - return Ycr0 - case REG_CR + 1: - return Ycr1 - case REG_CR + 2: - return Ycr2 - case REG_CR + 3: - return Ycr3 - case REG_CR + 4: - return Ycr4 - case REG_CR + 5: - return Ycr5 - case REG_CR + 6: - return Ycr6 - case REG_CR + 7: - return Ycr7 - case REG_CR + 8: - return Ycr8 - - case REG_DR + 0: - return Ydr0 - case REG_DR + 1: - return Ydr1 - case REG_DR + 2: - return Ydr2 - case REG_DR + 3: - return Ydr3 - case REG_DR + 4: - return Ydr4 - case REG_DR + 5: - return Ydr5 - case REG_DR + 6: - return Ydr6 - case REG_DR + 7: - return Ydr7 - - case REG_TR + 0: - return Ytr0 - case REG_TR + 1: - return Ytr1 - case REG_TR + 2: - return Ytr2 - case REG_TR + 3: - return Ytr3 - case REG_TR + 4: - return Ytr4 - case REG_TR + 5: - return Ytr5 - case REG_TR + 6: - return Ytr6 - case REG_TR + 7: - return Ytr7 - } - - return Yxxx -} - -func asmidx(ctxt *obj.Link, scale int, index int, base int) { - var i int - - switch index { - default: - goto bad - - case REG_NONE: - i = 4 << 3 - goto bas - - case REG_R8, - REG_R9, - REG_R10, - REG_R11, - REG_R12, - REG_R13, - REG_R14, - REG_R15: - if ctxt.Asmode != 64 { - goto bad - } - fallthrough - - case REG_AX, - REG_CX, - REG_DX, - REG_BX, - REG_BP, - REG_SI, - REG_DI: - i = reg[index] << 3 - } - - switch scale { - default: - goto bad - - case 1: - break - - case 2: - i |= 1 << 6 - - case 4: - i |= 2 << 6 - - case 8: - i |= 3 << 6 - } - -bas: - switch base { - default: - goto bad - - case REG_NONE: /* must be mod=00 */ - i |= 5 - - case REG_R8, - REG_R9, - REG_R10, - REG_R11, - REG_R12, - REG_R13, - REG_R14, - REG_R15: - if ctxt.Asmode != 64 { - goto bad - } - fallthrough - - case REG_AX, - REG_CX, - REG_DX, - REG_BX, - REG_SP, - REG_BP, - REG_SI, - REG_DI: - i |= reg[base] - } - - ctxt.AsmBuf.Put1(byte(i)) - return - -bad: - ctxt.Diag("asmidx: bad address %d/%d/%d", scale, index, base) - ctxt.AsmBuf.Put1(0) - return -} - -func relput4(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - var rel obj.Reloc - - v := vaddr(ctxt, p, a, &rel) - if rel.Siz != 0 { - if rel.Siz != 4 { - ctxt.Diag("bad reloc") - } - r := obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - } - - ctxt.AsmBuf.PutInt32(int32(v)) -} - -/* -static void -relput8(Prog *p, Addr *a) -{ - vlong v; - Reloc rel, *r; - - v = vaddr(ctxt, p, a, &rel); - if(rel.siz != 0) { - r = addrel(ctxt->cursym); - *r = rel; - r->siz = 8; - r->off = p->pc + ctxt->andptr - ctxt->and; - } - put8(ctxt, v); -} -*/ -func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 { - if r != nil { - *r = obj.Reloc{} - } - - switch a.Name { - case obj.NAME_STATIC, - obj.NAME_GOTREF, - obj.NAME_EXTERN: - s := a.Sym - if r == nil { - ctxt.Diag("need reloc for %v", obj.Dconv(p, a)) - log.Fatalf("reloc") - } - - if a.Name == obj.NAME_GOTREF { - r.Siz = 4 - r.Type = obj.R_GOTPCREL - } else if isextern(s) || (p.Mode != 64 && !ctxt.Flag_shared) { - r.Siz = 4 - r.Type = obj.R_ADDR - } else { - r.Siz = 4 - r.Type = obj.R_PCREL - } - - r.Off = -1 // caller must fill in - r.Sym = s - r.Add = a.Offset - - return 0 - } - - if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS { - if r == nil { - ctxt.Diag("need reloc for %v", obj.Dconv(p, a)) - log.Fatalf("reloc") - } - - if !ctxt.Flag_shared || isAndroid || ctxt.Headtype == obj.Hdarwin { - r.Type = obj.R_TLS_LE - r.Siz = 4 - r.Off = -1 // caller must fill in - r.Add = a.Offset - } - return 0 - } - - return a.Offset -} - -func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) { - var base int - var rel obj.Reloc - - rex &= 0x40 | Rxr - switch { - case int64(int32(a.Offset)) == a.Offset: - // Offset fits in sign-extended 32 bits. - case int64(uint32(a.Offset)) == a.Offset && ctxt.Rexflag&Rxw == 0: - // Offset fits in zero-extended 32 bits in a 32-bit instruction. - // This is allowed for assembly that wants to use 32-bit hex - // constants, e.g. LEAL 0x99999999(AX), AX. - default: - ctxt.Diag("offset too large in %s", p) - } - v := int32(a.Offset) - rel.Siz = 0 - - switch a.Type { - case obj.TYPE_ADDR: - if a.Name == obj.NAME_NONE { - ctxt.Diag("unexpected TYPE_ADDR with NAME_NONE") - } - if a.Index == REG_TLS { - ctxt.Diag("unexpected TYPE_ADDR with index==REG_TLS") - } - goto bad - - case obj.TYPE_REG: - if a.Reg < REG_AL || REG_Y0+15 < a.Reg { - goto bad - } - if v != 0 { - goto bad - } - ctxt.AsmBuf.Put1(byte(3<<6 | reg[a.Reg]<<0 | r<<3)) - ctxt.Rexflag |= regrex[a.Reg]&(0x40|Rxb) | rex - return - } - - if a.Type != obj.TYPE_MEM { - goto bad - } - - if a.Index != REG_NONE && a.Index != REG_TLS { - base := int(a.Reg) - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_GOTREF, - obj.NAME_STATIC: - if !isextern(a.Sym) && p.Mode == 64 { - goto bad - } - if p.Mode == 32 && ctxt.Flag_shared { - // The base register has already been set. It holds the PC - // of this instruction returned by a PC-reading thunk. - // See obj6.go:rewriteToPcrel. - } else { - base = REG_NONE - } - v = int32(vaddr(ctxt, p, a, &rel)) - - case obj.NAME_AUTO, - obj.NAME_PARAM: - base = REG_SP - } - - ctxt.Rexflag |= regrex[int(a.Index)]&Rxx | regrex[base]&Rxb | rex - if base == REG_NONE { - ctxt.AsmBuf.Put1(byte(0<<6 | 4<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), int(a.Index), base) - goto putrelv - } - - if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 { - ctxt.AsmBuf.Put1(byte(0<<6 | 4<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), int(a.Index), base) - return - } - - if v >= -128 && v < 128 && rel.Siz == 0 { - ctxt.AsmBuf.Put1(byte(1<<6 | 4<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), int(a.Index), base) - ctxt.AsmBuf.Put1(byte(v)) - return - } - - ctxt.AsmBuf.Put1(byte(2<<6 | 4<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), int(a.Index), base) - goto putrelv - } - - base = int(a.Reg) - switch a.Name { - case obj.NAME_STATIC, - obj.NAME_GOTREF, - obj.NAME_EXTERN: - if a.Sym == nil { - ctxt.Diag("bad addr: %v", p) - } - if p.Mode == 32 && ctxt.Flag_shared { - // The base register has already been set. It holds the PC - // of this instruction returned by a PC-reading thunk. - // See obj6.go:rewriteToPcrel. - } else { - base = REG_NONE - } - v = int32(vaddr(ctxt, p, a, &rel)) - - case obj.NAME_AUTO, - obj.NAME_PARAM: - base = REG_SP - } - - if base == REG_TLS { - v = int32(vaddr(ctxt, p, a, &rel)) - } - - ctxt.Rexflag |= regrex[base]&Rxb | rex - if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS { - if (a.Sym == nil || !isextern(a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || p.Mode != 64 { - if a.Name == obj.NAME_GOTREF && (a.Offset != 0 || a.Index != 0 || a.Scale != 0) { - ctxt.Diag("%v has offset against gotref", p) - } - ctxt.AsmBuf.Put1(byte(0<<6 | 5<<0 | r<<3)) - goto putrelv - } - - // temporary - ctxt.AsmBuf.Put2( - byte(0<<6|4<<0|r<<3), // sib present - 0<<6|4<<3|5<<0, // DS:d32 - ) - goto putrelv - } - - if base == REG_SP || base == REG_R12 { - if v == 0 { - ctxt.AsmBuf.Put1(byte(0<<6 | reg[base]<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), REG_NONE, base) - return - } - - if v >= -128 && v < 128 { - ctxt.AsmBuf.Put1(byte(1<<6 | reg[base]<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), REG_NONE, base) - ctxt.AsmBuf.Put1(byte(v)) - return - } - - ctxt.AsmBuf.Put1(byte(2<<6 | reg[base]<<0 | r<<3)) - asmidx(ctxt, int(a.Scale), REG_NONE, base) - goto putrelv - } - - if REG_AX <= base && base <= REG_R15 { - if a.Index == REG_TLS && !ctxt.Flag_shared { - rel = obj.Reloc{} - rel.Type = obj.R_TLS_LE - rel.Siz = 4 - rel.Sym = nil - rel.Add = int64(v) - v = 0 - } - - if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 { - ctxt.AsmBuf.Put1(byte(0<<6 | reg[base]<<0 | r<<3)) - return - } - - if v >= -128 && v < 128 && rel.Siz == 0 { - ctxt.AsmBuf.Put2(byte(1<<6|reg[base]<<0|r<<3), byte(v)) - return - } - - ctxt.AsmBuf.Put1(byte(2<<6 | reg[base]<<0 | r<<3)) - goto putrelv - } - - goto bad - -putrelv: - if rel.Siz != 0 { - if rel.Siz != 4 { - ctxt.Diag("bad rel") - goto bad - } - - r := obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(ctxt.Curp.Pc + int64(ctxt.AsmBuf.Len())) - } - - ctxt.AsmBuf.PutInt32(v) - return - -bad: - ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a)) - return -} - -func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, ra *obj.Addr) { - asmandsz(ctxt, p, a, reg[ra.Reg], regrex[ra.Reg], 0) -} - -func asmando(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, o int) { - asmandsz(ctxt, p, a, o, 0, 0) -} - -func bytereg(a *obj.Addr, t *uint8) { - if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AX <= a.Reg && a.Reg <= REG_R15) { - a.Reg += REG_AL - REG_AX - *t = 0 - } -} - -func unbytereg(a *obj.Addr, t *uint8) { - if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AL <= a.Reg && a.Reg <= REG_R15B) { - a.Reg += REG_AX - REG_AL - *t = 0 - } -} - -const ( - E = 0xff -) - -var ymovtab = []Movtab{ - /* push */ - {APUSHL, Ycs, Ynone, Ynone, 0, [4]uint8{0x0e, E, 0, 0}}, - {APUSHL, Yss, Ynone, Ynone, 0, [4]uint8{0x16, E, 0, 0}}, - {APUSHL, Yds, Ynone, Ynone, 0, [4]uint8{0x1e, E, 0, 0}}, - {APUSHL, Yes, Ynone, Ynone, 0, [4]uint8{0x06, E, 0, 0}}, - {APUSHL, Yfs, Ynone, Ynone, 0, [4]uint8{0x0f, 0xa0, E, 0}}, - {APUSHL, Ygs, Ynone, Ynone, 0, [4]uint8{0x0f, 0xa8, E, 0}}, - {APUSHQ, Yfs, Ynone, Ynone, 0, [4]uint8{0x0f, 0xa0, E, 0}}, - {APUSHQ, Ygs, Ynone, Ynone, 0, [4]uint8{0x0f, 0xa8, E, 0}}, - {APUSHW, Ycs, Ynone, Ynone, 0, [4]uint8{Pe, 0x0e, E, 0}}, - {APUSHW, Yss, Ynone, Ynone, 0, [4]uint8{Pe, 0x16, E, 0}}, - {APUSHW, Yds, Ynone, Ynone, 0, [4]uint8{Pe, 0x1e, E, 0}}, - {APUSHW, Yes, Ynone, Ynone, 0, [4]uint8{Pe, 0x06, E, 0}}, - {APUSHW, Yfs, Ynone, Ynone, 0, [4]uint8{Pe, 0x0f, 0xa0, E}}, - {APUSHW, Ygs, Ynone, Ynone, 0, [4]uint8{Pe, 0x0f, 0xa8, E}}, - - /* pop */ - {APOPL, Ynone, Ynone, Yds, 0, [4]uint8{0x1f, E, 0, 0}}, - {APOPL, Ynone, Ynone, Yes, 0, [4]uint8{0x07, E, 0, 0}}, - {APOPL, Ynone, Ynone, Yss, 0, [4]uint8{0x17, E, 0, 0}}, - {APOPL, Ynone, Ynone, Yfs, 0, [4]uint8{0x0f, 0xa1, E, 0}}, - {APOPL, Ynone, Ynone, Ygs, 0, [4]uint8{0x0f, 0xa9, E, 0}}, - {APOPQ, Ynone, Ynone, Yfs, 0, [4]uint8{0x0f, 0xa1, E, 0}}, - {APOPQ, Ynone, Ynone, Ygs, 0, [4]uint8{0x0f, 0xa9, E, 0}}, - {APOPW, Ynone, Ynone, Yds, 0, [4]uint8{Pe, 0x1f, E, 0}}, - {APOPW, Ynone, Ynone, Yes, 0, [4]uint8{Pe, 0x07, E, 0}}, - {APOPW, Ynone, Ynone, Yss, 0, [4]uint8{Pe, 0x17, E, 0}}, - {APOPW, Ynone, Ynone, Yfs, 0, [4]uint8{Pe, 0x0f, 0xa1, E}}, - {APOPW, Ynone, Ynone, Ygs, 0, [4]uint8{Pe, 0x0f, 0xa9, E}}, - - /* mov seg */ - {AMOVW, Yes, Ynone, Yml, 1, [4]uint8{0x8c, 0, 0, 0}}, - {AMOVW, Ycs, Ynone, Yml, 1, [4]uint8{0x8c, 1, 0, 0}}, - {AMOVW, Yss, Ynone, Yml, 1, [4]uint8{0x8c, 2, 0, 0}}, - {AMOVW, Yds, Ynone, Yml, 1, [4]uint8{0x8c, 3, 0, 0}}, - {AMOVW, Yfs, Ynone, Yml, 1, [4]uint8{0x8c, 4, 0, 0}}, - {AMOVW, Ygs, Ynone, Yml, 1, [4]uint8{0x8c, 5, 0, 0}}, - {AMOVW, Yml, Ynone, Yes, 2, [4]uint8{0x8e, 0, 0, 0}}, - {AMOVW, Yml, Ynone, Ycs, 2, [4]uint8{0x8e, 1, 0, 0}}, - {AMOVW, Yml, Ynone, Yss, 2, [4]uint8{0x8e, 2, 0, 0}}, - {AMOVW, Yml, Ynone, Yds, 2, [4]uint8{0x8e, 3, 0, 0}}, - {AMOVW, Yml, Ynone, Yfs, 2, [4]uint8{0x8e, 4, 0, 0}}, - {AMOVW, Yml, Ynone, Ygs, 2, [4]uint8{0x8e, 5, 0, 0}}, - - /* mov cr */ - {AMOVL, Ycr0, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 0, 0}}, - {AMOVL, Ycr2, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 2, 0}}, - {AMOVL, Ycr3, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 3, 0}}, - {AMOVL, Ycr4, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 4, 0}}, - {AMOVL, Ycr8, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 8, 0}}, - {AMOVQ, Ycr0, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 0, 0}}, - {AMOVQ, Ycr2, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 2, 0}}, - {AMOVQ, Ycr3, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 3, 0}}, - {AMOVQ, Ycr4, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 4, 0}}, - {AMOVQ, Ycr8, Ynone, Yml, 3, [4]uint8{0x0f, 0x20, 8, 0}}, - {AMOVL, Yml, Ynone, Ycr0, 4, [4]uint8{0x0f, 0x22, 0, 0}}, - {AMOVL, Yml, Ynone, Ycr2, 4, [4]uint8{0x0f, 0x22, 2, 0}}, - {AMOVL, Yml, Ynone, Ycr3, 4, [4]uint8{0x0f, 0x22, 3, 0}}, - {AMOVL, Yml, Ynone, Ycr4, 4, [4]uint8{0x0f, 0x22, 4, 0}}, - {AMOVL, Yml, Ynone, Ycr8, 4, [4]uint8{0x0f, 0x22, 8, 0}}, - {AMOVQ, Yml, Ynone, Ycr0, 4, [4]uint8{0x0f, 0x22, 0, 0}}, - {AMOVQ, Yml, Ynone, Ycr2, 4, [4]uint8{0x0f, 0x22, 2, 0}}, - {AMOVQ, Yml, Ynone, Ycr3, 4, [4]uint8{0x0f, 0x22, 3, 0}}, - {AMOVQ, Yml, Ynone, Ycr4, 4, [4]uint8{0x0f, 0x22, 4, 0}}, - {AMOVQ, Yml, Ynone, Ycr8, 4, [4]uint8{0x0f, 0x22, 8, 0}}, - - /* mov dr */ - {AMOVL, Ydr0, Ynone, Yml, 3, [4]uint8{0x0f, 0x21, 0, 0}}, - {AMOVL, Ydr6, Ynone, Yml, 3, [4]uint8{0x0f, 0x21, 6, 0}}, - {AMOVL, Ydr7, Ynone, Yml, 3, [4]uint8{0x0f, 0x21, 7, 0}}, - {AMOVQ, Ydr0, Ynone, Yml, 3, [4]uint8{0x0f, 0x21, 0, 0}}, - {AMOVQ, Ydr6, Ynone, Yml, 3, [4]uint8{0x0f, 0x21, 6, 0}}, - {AMOVQ, Ydr7, Ynone, Yml, 3, [4]uint8{0x0f, 0x21, 7, 0}}, - {AMOVL, Yml, Ynone, Ydr0, 4, [4]uint8{0x0f, 0x23, 0, 0}}, - {AMOVL, Yml, Ynone, Ydr6, 4, [4]uint8{0x0f, 0x23, 6, 0}}, - {AMOVL, Yml, Ynone, Ydr7, 4, [4]uint8{0x0f, 0x23, 7, 0}}, - {AMOVQ, Yml, Ynone, Ydr0, 4, [4]uint8{0x0f, 0x23, 0, 0}}, - {AMOVQ, Yml, Ynone, Ydr6, 4, [4]uint8{0x0f, 0x23, 6, 0}}, - {AMOVQ, Yml, Ynone, Ydr7, 4, [4]uint8{0x0f, 0x23, 7, 0}}, - - /* mov tr */ - {AMOVL, Ytr6, Ynone, Yml, 3, [4]uint8{0x0f, 0x24, 6, 0}}, - {AMOVL, Ytr7, Ynone, Yml, 3, [4]uint8{0x0f, 0x24, 7, 0}}, - {AMOVL, Yml, Ynone, Ytr6, 4, [4]uint8{0x0f, 0x26, 6, E}}, - {AMOVL, Yml, Ynone, Ytr7, 4, [4]uint8{0x0f, 0x26, 7, E}}, - - /* lgdt, sgdt, lidt, sidt */ - {AMOVL, Ym, Ynone, Ygdtr, 4, [4]uint8{0x0f, 0x01, 2, 0}}, - {AMOVL, Ygdtr, Ynone, Ym, 3, [4]uint8{0x0f, 0x01, 0, 0}}, - {AMOVL, Ym, Ynone, Yidtr, 4, [4]uint8{0x0f, 0x01, 3, 0}}, - {AMOVL, Yidtr, Ynone, Ym, 3, [4]uint8{0x0f, 0x01, 1, 0}}, - {AMOVQ, Ym, Ynone, Ygdtr, 4, [4]uint8{0x0f, 0x01, 2, 0}}, - {AMOVQ, Ygdtr, Ynone, Ym, 3, [4]uint8{0x0f, 0x01, 0, 0}}, - {AMOVQ, Ym, Ynone, Yidtr, 4, [4]uint8{0x0f, 0x01, 3, 0}}, - {AMOVQ, Yidtr, Ynone, Ym, 3, [4]uint8{0x0f, 0x01, 1, 0}}, - - /* lldt, sldt */ - {AMOVW, Yml, Ynone, Yldtr, 4, [4]uint8{0x0f, 0x00, 2, 0}}, - {AMOVW, Yldtr, Ynone, Yml, 3, [4]uint8{0x0f, 0x00, 0, 0}}, - - /* lmsw, smsw */ - {AMOVW, Yml, Ynone, Ymsw, 4, [4]uint8{0x0f, 0x01, 6, 0}}, - {AMOVW, Ymsw, Ynone, Yml, 3, [4]uint8{0x0f, 0x01, 4, 0}}, - - /* ltr, str */ - {AMOVW, Yml, Ynone, Ytask, 4, [4]uint8{0x0f, 0x00, 3, 0}}, - {AMOVW, Ytask, Ynone, Yml, 3, [4]uint8{0x0f, 0x00, 1, 0}}, - - /* load full pointer - unsupported - Movtab{AMOVL, Yml, Ycol, 5, [4]uint8{0, 0, 0, 0}}, - Movtab{AMOVW, Yml, Ycol, 5, [4]uint8{Pe, 0, 0, 0}}, - */ - - /* double shift */ - {ASHLL, Yi8, Yrl, Yml, 6, [4]uint8{0xa4, 0xa5, 0, 0}}, - {ASHLL, Ycl, Yrl, Yml, 6, [4]uint8{0xa4, 0xa5, 0, 0}}, - {ASHLL, Ycx, Yrl, Yml, 6, [4]uint8{0xa4, 0xa5, 0, 0}}, - {ASHRL, Yi8, Yrl, Yml, 6, [4]uint8{0xac, 0xad, 0, 0}}, - {ASHRL, Ycl, Yrl, Yml, 6, [4]uint8{0xac, 0xad, 0, 0}}, - {ASHRL, Ycx, Yrl, Yml, 6, [4]uint8{0xac, 0xad, 0, 0}}, - {ASHLQ, Yi8, Yrl, Yml, 6, [4]uint8{Pw, 0xa4, 0xa5, 0}}, - {ASHLQ, Ycl, Yrl, Yml, 6, [4]uint8{Pw, 0xa4, 0xa5, 0}}, - {ASHLQ, Ycx, Yrl, Yml, 6, [4]uint8{Pw, 0xa4, 0xa5, 0}}, - {ASHRQ, Yi8, Yrl, Yml, 6, [4]uint8{Pw, 0xac, 0xad, 0}}, - {ASHRQ, Ycl, Yrl, Yml, 6, [4]uint8{Pw, 0xac, 0xad, 0}}, - {ASHRQ, Ycx, Yrl, Yml, 6, [4]uint8{Pw, 0xac, 0xad, 0}}, - {ASHLW, Yi8, Yrl, Yml, 6, [4]uint8{Pe, 0xa4, 0xa5, 0}}, - {ASHLW, Ycl, Yrl, Yml, 6, [4]uint8{Pe, 0xa4, 0xa5, 0}}, - {ASHLW, Ycx, Yrl, Yml, 6, [4]uint8{Pe, 0xa4, 0xa5, 0}}, - {ASHRW, Yi8, Yrl, Yml, 6, [4]uint8{Pe, 0xac, 0xad, 0}}, - {ASHRW, Ycl, Yrl, Yml, 6, [4]uint8{Pe, 0xac, 0xad, 0}}, - {ASHRW, Ycx, Yrl, Yml, 6, [4]uint8{Pe, 0xac, 0xad, 0}}, - - /* load TLS base */ - {AMOVL, Ytls, Ynone, Yrl, 7, [4]uint8{0, 0, 0, 0}}, - {AMOVQ, Ytls, Ynone, Yrl, 7, [4]uint8{0, 0, 0, 0}}, - {0, 0, 0, 0, 0, [4]uint8{}}, -} - -func isax(a *obj.Addr) bool { - switch a.Reg { - case REG_AX, REG_AL, REG_AH: - return true - } - - if a.Index == REG_AX { - return true - } - return false -} - -func subreg(p *obj.Prog, from int, to int) { - if false { /* debug['Q'] */ - fmt.Printf("\n%v\ts/%v/%v/\n", p, Rconv(from), Rconv(to)) - } - - if int(p.From.Reg) == from { - p.From.Reg = int16(to) - p.Ft = 0 - } - - if int(p.To.Reg) == from { - p.To.Reg = int16(to) - p.Tt = 0 - } - - if int(p.From.Index) == from { - p.From.Index = int16(to) - p.Ft = 0 - } - - if int(p.To.Index) == from { - p.To.Index = int16(to) - p.Tt = 0 - } - - if false { /* debug['Q'] */ - fmt.Printf("%v\n", p) - } -} - -func mediaop(ctxt *obj.Link, o *Optab, op int, osize int, z int) int { - switch op { - case Pm, Pe, Pf2, Pf3: - if osize != 1 { - if op != Pm { - ctxt.AsmBuf.Put1(byte(op)) - } - ctxt.AsmBuf.Put1(Pm) - z++ - op = int(o.op[z]) - break - } - fallthrough - - default: - if ctxt.AsmBuf.Len() == 0 || ctxt.AsmBuf.Last() != Pm { - ctxt.AsmBuf.Put1(Pm) - } - } - - ctxt.AsmBuf.Put1(byte(op)) - return z -} - -var bpduff1 = []byte{ - 0x48, 0x89, 0x6c, 0x24, 0xf0, // MOVQ BP, -16(SP) - 0x48, 0x8d, 0x6c, 0x24, 0xf0, // LEAQ -16(SP), BP -} - -var bpduff2 = []byte{ - 0x48, 0x8b, 0x6d, 0x00, // MOVQ 0(BP), BP -} - -// Emit VEX prefix and opcode byte. -// The three addresses are the r/m, vvvv, and reg fields. -// The reg and rm arguments appear in the same order as the -// arguments to asmand, which typically follows the call to asmvex. -// The final two arguments are the VEX prefix (see encoding above) -// and the opcode byte. -// For details about vex prefix see: -// https://en.wikipedia.org/wiki/VEX_prefix#Technical_description -func asmvex(ctxt *obj.Link, rm, v, r *obj.Addr, vex, opcode uint8) { - ctxt.Vexflag = 1 - rexR := 0 - if r != nil { - rexR = regrex[r.Reg] & Rxr - } - rexB := 0 - rexX := 0 - if rm != nil { - rexB = regrex[rm.Reg] & Rxb - rexX = regrex[rm.Index] & Rxx - } - vexM := (vex >> 3) & 0xF - vexWLP := vex & 0x87 - vexV := byte(0) - if v != nil { - vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF - } - vexV ^= 0xF - if vexM == 1 && (rexX|rexB) == 0 && vex&vexW1 == 0 { - // Can use 2-byte encoding. - ctxt.AsmBuf.Put2(0xc5, byte(rexR<<5)^0x80|vexV<<3|vexWLP) - } else { - // Must use 3-byte encoding. - ctxt.AsmBuf.Put3(0xc4, - (byte(rexR|rexX|rexB)<<5)^0xE0|vexM, - vexV<<3|vexWLP, - ) - } - ctxt.AsmBuf.Put1(opcode) -} - -func doasm(ctxt *obj.Link, p *obj.Prog) { - ctxt.Curp = p // TODO - - o := opindex[p.As&obj.AMask] - - if o == nil { - ctxt.Diag("asmins: missing op %v", p) - return - } - - pre := prefixof(ctxt, p, &p.From) - if pre != 0 { - ctxt.AsmBuf.Put1(byte(pre)) - } - pre = prefixof(ctxt, p, &p.To) - if pre != 0 { - ctxt.AsmBuf.Put1(byte(pre)) - } - - // TODO(rsc): This special case is for SHRQ $3, AX:DX, - // which encodes as SHRQ $32(DX*0), AX. - // Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX. - // Change encoding generated by assemblers and compilers and remove. - if (p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_REG) && p.From.Index != REG_NONE && p.From.Scale == 0 { - p.From3 = new(obj.Addr) - p.From3.Type = obj.TYPE_REG - p.From3.Reg = p.From.Index - p.From.Index = 0 - } - - // TODO(rsc): This special case is for PINSRQ etc, CMPSD etc. - // Change encoding generated by assemblers and compilers (if any) and remove. - switch p.As { - case AIMUL3Q, APEXTRW, APINSRW, APINSRD, APINSRQ, APSHUFHW, APSHUFL, APSHUFW, ASHUFPD, ASHUFPS, AAESKEYGENASSIST, APSHUFD, APCLMULQDQ: - if p.From3Type() == obj.TYPE_NONE { - p.From3 = new(obj.Addr) - *p.From3 = p.From - p.From = obj.Addr{} - p.From.Type = obj.TYPE_CONST - p.From.Offset = p.To.Offset - p.To.Offset = 0 - } - case ACMPSD, ACMPSS, ACMPPS, ACMPPD: - if p.From3Type() == obj.TYPE_NONE { - p.From3 = new(obj.Addr) - *p.From3 = p.To - p.To = obj.Addr{} - p.To.Type = obj.TYPE_CONST - p.To.Offset = p.From3.Offset - p.From3.Offset = 0 - } - } - - if p.Ft == 0 { - p.Ft = uint8(oclass(ctxt, p, &p.From)) - } - if p.Tt == 0 { - p.Tt = uint8(oclass(ctxt, p, &p.To)) - } - - ft := int(p.Ft) * Ymax - f3t := Ynone * Ymax - if p.From3 != nil { - f3t = oclass(ctxt, p, p.From3) * Ymax - } - tt := int(p.Tt) * Ymax - - xo := obj.Bool2int(o.op[0] == 0x0f) - z := 0 - var a *obj.Addr - var l int - var op int - var q *obj.Prog - var r *obj.Reloc - var rel obj.Reloc - var v int64 - for i := range o.ytab { - yt := &o.ytab[i] - if ycover[ft+int(yt.from)] != 0 && ycover[f3t+int(yt.from3)] != 0 && ycover[tt+int(yt.to)] != 0 { - switch o.prefix { - case Px1: /* first option valid only in 32-bit mode */ - if ctxt.Mode == 64 && z == 0 { - z += int(yt.zoffset) + xo - continue - } - case Pq: /* 16 bit escape and opcode escape */ - ctxt.AsmBuf.Put2(Pe, Pm) - - case Pq3: /* 16 bit escape and opcode escape + REX.W */ - ctxt.Rexflag |= Pw - ctxt.AsmBuf.Put2(Pe, Pm) - - case Pq4: /* 66 0F 38 */ - ctxt.AsmBuf.Put3(0x66, 0x0F, 0x38) - - case Pf2, /* xmm opcode escape */ - Pf3: - ctxt.AsmBuf.Put2(o.prefix, Pm) - - case Pef3: - ctxt.AsmBuf.Put3(Pe, Pf3, Pm) - - case Pfw: /* xmm opcode escape + REX.W */ - ctxt.Rexflag |= Pw - ctxt.AsmBuf.Put2(Pf3, Pm) - - case Pm: /* opcode escape */ - ctxt.AsmBuf.Put1(Pm) - - case Pe: /* 16 bit escape */ - ctxt.AsmBuf.Put1(Pe) - - case Pw: /* 64-bit escape */ - if p.Mode != 64 { - ctxt.Diag("asmins: illegal 64: %v", p) - } - ctxt.Rexflag |= Pw - - case Pw8: /* 64-bit escape if z >= 8 */ - if z >= 8 { - if p.Mode != 64 { - ctxt.Diag("asmins: illegal 64: %v", p) - } - ctxt.Rexflag |= Pw - } - - case Pb: /* botch */ - if p.Mode != 64 && (isbadbyte(&p.From) || isbadbyte(&p.To)) { - goto bad - } - // NOTE(rsc): This is probably safe to do always, - // but when enabled it chooses different encodings - // than the old cmd/internal/obj/i386 code did, - // which breaks our "same bits out" checks. - // In particular, CMPB AX, $0 encodes as 80 f8 00 - // in the original obj/i386, and it would encode - // (using a valid, shorter form) as 3c 00 if we enabled - // the call to bytereg here. - if p.Mode == 64 { - bytereg(&p.From, &p.Ft) - bytereg(&p.To, &p.Tt) - } - - case P32: /* 32 bit but illegal if 64-bit mode */ - if p.Mode == 64 { - ctxt.Diag("asmins: illegal in 64-bit mode: %v", p) - } - - case Py: /* 64-bit only, no prefix */ - if p.Mode != 64 { - ctxt.Diag("asmins: illegal in %d-bit mode: %v", p.Mode, p) - } - - case Py1: /* 64-bit only if z < 1, no prefix */ - if z < 1 && p.Mode != 64 { - ctxt.Diag("asmins: illegal in %d-bit mode: %v", p.Mode, p) - } - - case Py3: /* 64-bit only if z < 3, no prefix */ - if z < 3 && p.Mode != 64 { - ctxt.Diag("asmins: illegal in %d-bit mode: %v", p.Mode, p) - } - } - - if z >= len(o.op) { - log.Fatalf("asmins bad table %v", p) - } - op = int(o.op[z]) - // In vex case 0x0f is actually VEX_256_F2_0F_WIG - if op == 0x0f && o.prefix != Pvex { - ctxt.AsmBuf.Put1(byte(op)) - z++ - op = int(o.op[z]) - } - - switch yt.zcase { - default: - ctxt.Diag("asmins: unknown z %d %v", yt.zcase, p) - return - - case Zpseudo: - break - - case Zlit: - for ; ; z++ { - op = int(o.op[z]) - if op == 0 { - break - } - ctxt.AsmBuf.Put1(byte(op)) - } - - case Zlitm_r: - for ; ; z++ { - op = int(o.op[z]) - if op == 0 { - break - } - ctxt.AsmBuf.Put1(byte(op)) - } - asmand(ctxt, p, &p.From, &p.To) - - case Zmb_r: - bytereg(&p.From, &p.Ft) - fallthrough - - case Zm_r: - ctxt.AsmBuf.Put1(byte(op)) - asmand(ctxt, p, &p.From, &p.To) - - case Zm2_r: - ctxt.AsmBuf.Put2(byte(op), o.op[z+1]) - asmand(ctxt, p, &p.From, &p.To) - - case Zm_r_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.From, &p.To) - - case Zm_r_xm_nr: - ctxt.Rexflag = 0 - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.From, &p.To) - - case Zm_r_i_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.From, p.From3) - ctxt.AsmBuf.Put1(byte(p.To.Offset)) - - case Zibm_r, Zibr_m: - for { - tmp1 := z - z++ - op = int(o.op[tmp1]) - if op == 0 { - break - } - ctxt.AsmBuf.Put1(byte(op)) - } - if yt.zcase == Zibr_m { - asmand(ctxt, p, &p.To, p.From3) - } else { - asmand(ctxt, p, p.From3, &p.To) - } - ctxt.AsmBuf.Put1(byte(p.From.Offset)) - - case Zaut_r: - ctxt.AsmBuf.Put1(0x8d) // leal - if p.From.Type != obj.TYPE_ADDR { - ctxt.Diag("asmins: Zaut sb type ADDR") - } - p.From.Type = obj.TYPE_MEM - asmand(ctxt, p, &p.From, &p.To) - p.From.Type = obj.TYPE_ADDR - - case Zm_o: - ctxt.AsmBuf.Put1(byte(op)) - asmando(ctxt, p, &p.From, int(o.op[z+1])) - - case Zr_m: - ctxt.AsmBuf.Put1(byte(op)) - asmand(ctxt, p, &p.To, &p.From) - - case Zvex_rm_v_r: - asmvex(ctxt, &p.From, p.From3, &p.To, o.op[z], o.op[z+1]) - asmand(ctxt, p, &p.From, &p.To) - - case Zvex_i_r_v: - asmvex(ctxt, p.From3, &p.To, nil, o.op[z], o.op[z+1]) - regnum := byte(0x7) - if p.From3.Reg >= REG_X0 && p.From3.Reg <= REG_X15 { - regnum &= byte(p.From3.Reg - REG_X0) - } else { - regnum &= byte(p.From3.Reg - REG_Y0) - } - ctxt.AsmBuf.Put1(byte(o.op[z+2]) | regnum) - ctxt.AsmBuf.Put1(byte(p.From.Offset)) - - case Zvex_i_rm_v_r: - asmvex(ctxt, &p.From, p.From3, &p.To, o.op[z], o.op[z+1]) - asmand(ctxt, p, &p.From, &p.To) - ctxt.AsmBuf.Put1(byte(p.From3.Offset)) - - case Zvex_i_rm_r: - asmvex(ctxt, p.From3, nil, &p.To, o.op[z], o.op[z+1]) - asmand(ctxt, p, p.From3, &p.To) - ctxt.AsmBuf.Put1(byte(p.From.Offset)) - - case Zvex_v_rm_r: - asmvex(ctxt, p.From3, &p.From, &p.To, o.op[z], o.op[z+1]) - asmand(ctxt, p, p.From3, &p.To) - - case Zvex_r_v_rm: - asmvex(ctxt, &p.To, p.From3, &p.From, o.op[z], o.op[z+1]) - asmand(ctxt, p, &p.To, &p.From) - - case Zr_m_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.To, &p.From) - - case Zr_m_xm_nr: - ctxt.Rexflag = 0 - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.To, &p.From) - - case Zo_m: - ctxt.AsmBuf.Put1(byte(op)) - asmando(ctxt, p, &p.To, int(o.op[z+1])) - - case Zcallindreg: - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc) - r.Type = obj.R_CALLIND - r.Siz = 0 - fallthrough - - case Zo_m64: - ctxt.AsmBuf.Put1(byte(op)) - asmandsz(ctxt, p, &p.To, int(o.op[z+1]), 0, 1) - - case Zm_ibo: - ctxt.AsmBuf.Put1(byte(op)) - asmando(ctxt, p, &p.From, int(o.op[z+1])) - ctxt.AsmBuf.Put1(byte(vaddr(ctxt, p, &p.To, nil))) - - case Zibo_m: - ctxt.AsmBuf.Put1(byte(op)) - asmando(ctxt, p, &p.To, int(o.op[z+1])) - ctxt.AsmBuf.Put1(byte(vaddr(ctxt, p, &p.From, nil))) - - case Zibo_m_xm: - z = mediaop(ctxt, o, op, int(yt.zoffset), z) - asmando(ctxt, p, &p.To, int(o.op[z+1])) - ctxt.AsmBuf.Put1(byte(vaddr(ctxt, p, &p.From, nil))) - - case Z_ib, Zib_: - if yt.zcase == Zib_ { - a = &p.From - } else { - a = &p.To - } - ctxt.AsmBuf.Put1(byte(op)) - if p.As == AXABORT { - ctxt.AsmBuf.Put1(o.op[z+1]) - } - ctxt.AsmBuf.Put1(byte(vaddr(ctxt, p, a, nil))) - - case Zib_rp: - ctxt.Rexflag |= regrex[p.To.Reg] & (Rxb | 0x40) - ctxt.AsmBuf.Put2(byte(op+reg[p.To.Reg]), byte(vaddr(ctxt, p, &p.From, nil))) - - case Zil_rp: - ctxt.Rexflag |= regrex[p.To.Reg] & Rxb - ctxt.AsmBuf.Put1(byte(op + reg[p.To.Reg])) - if o.prefix == Pe { - v = vaddr(ctxt, p, &p.From, nil) - ctxt.AsmBuf.PutInt16(int16(v)) - } else { - relput4(ctxt, p, &p.From) - } - - case Zo_iw: - ctxt.AsmBuf.Put1(byte(op)) - if p.From.Type != obj.TYPE_NONE { - v = vaddr(ctxt, p, &p.From, nil) - ctxt.AsmBuf.PutInt16(int16(v)) - } - - case Ziq_rp: - v = vaddr(ctxt, p, &p.From, &rel) - l = int(v >> 32) - if l == 0 && rel.Siz != 8 { - //p->mark |= 0100; - //print("zero: %llux %v\n", v, p); - ctxt.Rexflag &^= (0x40 | Rxw) - - ctxt.Rexflag |= regrex[p.To.Reg] & Rxb - ctxt.AsmBuf.Put1(byte(0xb8 + reg[p.To.Reg])) - if rel.Type != 0 { - r = obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - } - - ctxt.AsmBuf.PutInt32(int32(v)) - } else if l == -1 && uint64(v)&(uint64(1)<<31) != 0 { /* sign extend */ - - //p->mark |= 0100; - //print("sign: %llux %v\n", v, p); - ctxt.AsmBuf.Put1(0xc7) - asmando(ctxt, p, &p.To, 0) - - ctxt.AsmBuf.PutInt32(int32(v)) // need all 8 - } else { - //print("all: %llux %v\n", v, p); - ctxt.Rexflag |= regrex[p.To.Reg] & Rxb - ctxt.AsmBuf.Put1(byte(op + reg[p.To.Reg])) - if rel.Type != 0 { - r = obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - } - - ctxt.AsmBuf.PutInt64(v) - } - - case Zib_rr: - ctxt.AsmBuf.Put1(byte(op)) - asmand(ctxt, p, &p.To, &p.To) - ctxt.AsmBuf.Put1(byte(vaddr(ctxt, p, &p.From, nil))) - - case Z_il, Zil_: - if yt.zcase == Zil_ { - a = &p.From - } else { - a = &p.To - } - ctxt.AsmBuf.Put1(byte(op)) - if o.prefix == Pe { - v = vaddr(ctxt, p, a, nil) - ctxt.AsmBuf.PutInt16(int16(v)) - } else { - relput4(ctxt, p, a) - } - - case Zm_ilo, Zilo_m: - ctxt.AsmBuf.Put1(byte(op)) - if yt.zcase == Zilo_m { - a = &p.From - asmando(ctxt, p, &p.To, int(o.op[z+1])) - } else { - a = &p.To - asmando(ctxt, p, &p.From, int(o.op[z+1])) - } - - if o.prefix == Pe { - v = vaddr(ctxt, p, a, nil) - ctxt.AsmBuf.PutInt16(int16(v)) - } else { - relput4(ctxt, p, a) - } - - case Zil_rr: - ctxt.AsmBuf.Put1(byte(op)) - asmand(ctxt, p, &p.To, &p.To) - if o.prefix == Pe { - v = vaddr(ctxt, p, &p.From, nil) - ctxt.AsmBuf.PutInt16(int16(v)) - } else { - relput4(ctxt, p, &p.From) - } - - case Z_rp: - ctxt.Rexflag |= regrex[p.To.Reg] & (Rxb | 0x40) - ctxt.AsmBuf.Put1(byte(op + reg[p.To.Reg])) - - case Zrp_: - ctxt.Rexflag |= regrex[p.From.Reg] & (Rxb | 0x40) - ctxt.AsmBuf.Put1(byte(op + reg[p.From.Reg])) - - case Zclr: - ctxt.Rexflag &^= Pw - ctxt.AsmBuf.Put1(byte(op)) - asmand(ctxt, p, &p.To, &p.To) - - case Zcallcon, Zjmpcon: - if yt.zcase == Zcallcon { - ctxt.AsmBuf.Put1(byte(op)) - } else { - ctxt.AsmBuf.Put1(o.op[z+1]) - } - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - r.Type = obj.R_PCREL - r.Siz = 4 - r.Add = p.To.Offset - ctxt.AsmBuf.PutInt32(0) - - case Zcallind: - ctxt.AsmBuf.Put2(byte(op), o.op[z+1]) - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - if p.Mode == 64 { - r.Type = obj.R_PCREL - } else { - r.Type = obj.R_ADDR - } - r.Siz = 4 - r.Add = p.To.Offset - r.Sym = p.To.Sym - ctxt.AsmBuf.PutInt32(0) - - case Zcall, Zcallduff: - if p.To.Sym == nil { - ctxt.Diag("call without target") - log.Fatalf("bad code") - } - - if yt.zcase == Zcallduff && ctxt.Flag_dynlink { - ctxt.Diag("directly calling duff when dynamically linking Go") - } - - if ctxt.Framepointer_enabled && yt.zcase == Zcallduff && p.Mode == 64 { - // Maintain BP around call, since duffcopy/duffzero can't do it - // (the call jumps into the middle of the function). - // This makes it possible to see call sites for duffcopy/duffzero in - // BP-based profiling tools like Linux perf (which is the - // whole point of obj.Framepointer_enabled). - // MOVQ BP, -16(SP) - // LEAQ -16(SP), BP - ctxt.AsmBuf.Put(bpduff1) - } - ctxt.AsmBuf.Put1(byte(op)) - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - r.Sym = p.To.Sym - r.Add = p.To.Offset - r.Type = obj.R_CALL - r.Siz = 4 - ctxt.AsmBuf.PutInt32(0) - - if ctxt.Framepointer_enabled && yt.zcase == Zcallduff && p.Mode == 64 { - // Pop BP pushed above. - // MOVQ 0(BP), BP - ctxt.AsmBuf.Put(bpduff2) - } - - // TODO: jump across functions needs reloc - case Zbr, Zjmp, Zloop: - if p.As == AXBEGIN { - ctxt.AsmBuf.Put1(byte(op)) - } - if p.To.Sym != nil { - if yt.zcase != Zjmp { - ctxt.Diag("branch to ATEXT") - log.Fatalf("bad code") - } - - ctxt.AsmBuf.Put1(o.op[z+1]) - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - r.Sym = p.To.Sym - r.Type = obj.R_PCREL - r.Siz = 4 - ctxt.AsmBuf.PutInt32(0) - break - } - - // Assumes q is in this function. - // TODO: Check in input, preserve in brchain. - - // Fill in backward jump now. - q = p.Pcond - - if q == nil { - ctxt.Diag("jmp/branch/loop without target") - log.Fatalf("bad code") - } - - if p.Back&1 != 0 { - v = q.Pc - (p.Pc + 2) - if v >= -128 && p.As != AXBEGIN { - if p.As == AJCXZL { - ctxt.AsmBuf.Put1(0x67) - } - ctxt.AsmBuf.Put2(byte(op), byte(v)) - } else if yt.zcase == Zloop { - ctxt.Diag("loop too far: %v", p) - } else { - v -= 5 - 2 - if p.As == AXBEGIN { - v-- - } - if yt.zcase == Zbr { - ctxt.AsmBuf.Put1(0x0f) - v-- - } - - ctxt.AsmBuf.Put1(o.op[z+1]) - ctxt.AsmBuf.PutInt32(int32(v)) - } - - break - } - - // Annotate target; will fill in later. - p.Forwd = q.Rel - - q.Rel = p - if p.Back&2 != 0 && p.As != AXBEGIN { // short - if p.As == AJCXZL { - ctxt.AsmBuf.Put1(0x67) - } - ctxt.AsmBuf.Put2(byte(op), 0) - } else if yt.zcase == Zloop { - ctxt.Diag("loop too far: %v", p) - } else { - if yt.zcase == Zbr { - ctxt.AsmBuf.Put1(0x0f) - } - ctxt.AsmBuf.Put1(o.op[z+1]) - ctxt.AsmBuf.PutInt32(0) - } - - break - - /* - v = q->pc - p->pc - 2; - if((v >= -128 && v <= 127) || p->pc == -1 || q->pc == -1) { - *ctxt->andptr++ = op; - *ctxt->andptr++ = v; - } else { - v -= 5-2; - if(yt.zcase == Zbr) { - *ctxt->andptr++ = 0x0f; - v--; - } - *ctxt->andptr++ = o->op[z+1]; - *ctxt->andptr++ = v; - *ctxt->andptr++ = v>>8; - *ctxt->andptr++ = v>>16; - *ctxt->andptr++ = v>>24; - } - */ - - case Zbyte: - v = vaddr(ctxt, p, &p.From, &rel) - if rel.Siz != 0 { - rel.Siz = uint8(op) - r = obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - } - - ctxt.AsmBuf.Put1(byte(v)) - if op > 1 { - ctxt.AsmBuf.Put1(byte(v >> 8)) - if op > 2 { - ctxt.AsmBuf.PutInt16(int16(v >> 16)) - if op > 4 { - ctxt.AsmBuf.PutInt32(int32(v >> 32)) - } - } - } - } - - return - } - z += int(yt.zoffset) + xo - } - for mo := ymovtab; mo[0].as != 0; mo = mo[1:] { - var pp obj.Prog - var t []byte - if p.As == mo[0].as { - if ycover[ft+int(mo[0].ft)] != 0 && ycover[f3t+int(mo[0].f3t)] != 0 && ycover[tt+int(mo[0].tt)] != 0 { - t = mo[0].op[:] - switch mo[0].code { - default: - ctxt.Diag("asmins: unknown mov %d %v", mo[0].code, p) - - case 0: /* lit */ - for z = 0; t[z] != E; z++ { - ctxt.AsmBuf.Put1(t[z]) - } - - case 1: /* r,m */ - ctxt.AsmBuf.Put1(t[0]) - asmando(ctxt, p, &p.To, int(t[1])) - - case 2: /* m,r */ - ctxt.AsmBuf.Put1(t[0]) - asmando(ctxt, p, &p.From, int(t[1])) - - case 3: /* r,m - 2op */ - ctxt.AsmBuf.Put2(t[0], t[1]) - asmando(ctxt, p, &p.To, int(t[2])) - ctxt.Rexflag |= regrex[p.From.Reg] & (Rxr | 0x40) - - case 4: /* m,r - 2op */ - ctxt.AsmBuf.Put2(t[0], t[1]) - asmando(ctxt, p, &p.From, int(t[2])) - ctxt.Rexflag |= regrex[p.To.Reg] & (Rxr | 0x40) - - case 5: /* load full pointer, trash heap */ - if t[0] != 0 { - ctxt.AsmBuf.Put1(t[0]) - } - switch p.To.Index { - default: - goto bad - - case REG_DS: - ctxt.AsmBuf.Put1(0xc5) - - case REG_SS: - ctxt.AsmBuf.Put2(0x0f, 0xb2) - - case REG_ES: - ctxt.AsmBuf.Put1(0xc4) - - case REG_FS: - ctxt.AsmBuf.Put2(0x0f, 0xb4) - - case REG_GS: - ctxt.AsmBuf.Put2(0x0f, 0xb5) - } - - asmand(ctxt, p, &p.From, &p.To) - - case 6: /* double shift */ - if t[0] == Pw { - if p.Mode != 64 { - ctxt.Diag("asmins: illegal 64: %v", p) - } - ctxt.Rexflag |= Pw - t = t[1:] - } else if t[0] == Pe { - ctxt.AsmBuf.Put1(Pe) - t = t[1:] - } - - switch p.From.Type { - default: - goto bad - - case obj.TYPE_CONST: - ctxt.AsmBuf.Put2(0x0f, t[0]) - asmandsz(ctxt, p, &p.To, reg[p.From3.Reg], regrex[p.From3.Reg], 0) - ctxt.AsmBuf.Put1(byte(p.From.Offset)) - - case obj.TYPE_REG: - switch p.From.Reg { - default: - goto bad - - case REG_CL, REG_CX: - ctxt.AsmBuf.Put2(0x0f, t[1]) - asmandsz(ctxt, p, &p.To, reg[p.From3.Reg], regrex[p.From3.Reg], 0) - } - } - - // NOTE: The systems listed here are the ones that use the "TLS initial exec" model, - // where you load the TLS base register into a register and then index off that - // register to access the actual TLS variables. Systems that allow direct TLS access - // are handled in prefixof above and should not be listed here. - case 7: /* mov tls, r */ - if p.Mode == 64 && p.As != AMOVQ || p.Mode == 32 && p.As != AMOVL { - ctxt.Diag("invalid load of TLS: %v", p) - } - - if p.Mode == 32 { - // NOTE: The systems listed here are the ones that use the "TLS initial exec" model, - // where you load the TLS base register into a register and then index off that - // register to access the actual TLS variables. Systems that allow direct TLS access - // are handled in prefixof above and should not be listed here. - switch ctxt.Headtype { - default: - log.Fatalf("unknown TLS base location for %v", ctxt.Headtype) - - case obj.Hlinux, - obj.Hnacl: - if ctxt.Flag_shared { - // Note that this is not generating the same insns as the other cases. - // MOV TLS, dst - // becomes - // call __x86.get_pc_thunk.dst - // movl (gotpc + g@gotntpoff)(dst), dst - // which is encoded as - // call __x86.get_pc_thunk.dst - // movq 0(dst), dst - // and R_CALL & R_TLS_IE relocs. This all assumes the only tls variable we access - // is g, which we can't check here, but will when we assemble the second - // instruction. - dst := p.To.Reg - ctxt.AsmBuf.Put1(0xe8) - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - r.Type = obj.R_CALL - r.Siz = 4 - r.Sym = obj.Linklookup(ctxt, "__x86.get_pc_thunk."+strings.ToLower(Rconv(int(dst))), 0) - ctxt.AsmBuf.PutInt32(0) - - ctxt.AsmBuf.Put2(0x8B, byte(2<<6|reg[dst]|(reg[dst]<<3))) - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - r.Type = obj.R_TLS_IE - r.Siz = 4 - r.Add = 2 - ctxt.AsmBuf.PutInt32(0) - } else { - // ELF TLS base is 0(GS). - pp.From = p.From - - pp.From.Type = obj.TYPE_MEM - pp.From.Reg = REG_GS - pp.From.Offset = 0 - pp.From.Index = REG_NONE - pp.From.Scale = 0 - ctxt.AsmBuf.Put2(0x65, // GS - 0x8B) - asmand(ctxt, p, &pp.From, &p.To) - } - case obj.Hplan9: - if ctxt.Plan9privates == nil { - ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) - } - pp.From = obj.Addr{} - pp.From.Type = obj.TYPE_MEM - pp.From.Name = obj.NAME_EXTERN - pp.From.Sym = ctxt.Plan9privates - pp.From.Offset = 0 - pp.From.Index = REG_NONE - ctxt.AsmBuf.Put1(0x8B) - asmand(ctxt, p, &pp.From, &p.To) - - case obj.Hwindows, obj.Hwindowsgui: - // Windows TLS base is always 0x14(FS). - pp.From = p.From - - pp.From.Type = obj.TYPE_MEM - pp.From.Reg = REG_FS - pp.From.Offset = 0x14 - pp.From.Index = REG_NONE - pp.From.Scale = 0 - ctxt.AsmBuf.Put2(0x64, // FS - 0x8B) - asmand(ctxt, p, &pp.From, &p.To) - } - break - } - - switch ctxt.Headtype { - default: - log.Fatalf("unknown TLS base location for %v", ctxt.Headtype) - - case obj.Hlinux: - if !ctxt.Flag_shared { - log.Fatalf("unknown TLS base location for linux without -shared") - } - // Note that this is not generating the same insn as the other cases. - // MOV TLS, R_to - // becomes - // movq g@gottpoff(%rip), R_to - // which is encoded as - // movq 0(%rip), R_to - // and a R_TLS_IE reloc. This all assumes the only tls variable we access - // is g, which we can't check here, but will when we assemble the second - // instruction. - ctxt.Rexflag = Pw | (regrex[p.To.Reg] & Rxr) - - ctxt.AsmBuf.Put2(0x8B, byte(0x05|(reg[p.To.Reg]<<3))) - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(ctxt.AsmBuf.Len())) - r.Type = obj.R_TLS_IE - r.Siz = 4 - r.Add = -4 - ctxt.AsmBuf.PutInt32(0) - - case obj.Hplan9: - if ctxt.Plan9privates == nil { - ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) - } - pp.From = obj.Addr{} - pp.From.Type = obj.TYPE_MEM - pp.From.Name = obj.NAME_EXTERN - pp.From.Sym = ctxt.Plan9privates - pp.From.Offset = 0 - pp.From.Index = REG_NONE - ctxt.Rexflag |= Pw - ctxt.AsmBuf.Put1(0x8B) - asmand(ctxt, p, &pp.From, &p.To) - - case obj.Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c. - // TLS base is 0(FS). - pp.From = p.From - - pp.From.Type = obj.TYPE_MEM - pp.From.Name = obj.NAME_NONE - pp.From.Reg = REG_NONE - pp.From.Offset = 0 - pp.From.Index = REG_NONE - pp.From.Scale = 0 - ctxt.Rexflag |= Pw - ctxt.AsmBuf.Put2(0x64, // FS - 0x8B) - asmand(ctxt, p, &pp.From, &p.To) - - case obj.Hwindows, obj.Hwindowsgui: - // Windows TLS base is always 0x28(GS). - pp.From = p.From - - pp.From.Type = obj.TYPE_MEM - pp.From.Name = obj.NAME_NONE - pp.From.Reg = REG_GS - pp.From.Offset = 0x28 - pp.From.Index = REG_NONE - pp.From.Scale = 0 - ctxt.Rexflag |= Pw - ctxt.AsmBuf.Put2(0x65, // GS - 0x8B) - asmand(ctxt, p, &pp.From, &p.To) - } - } - return - } - } - } - goto bad - -bad: - if p.Mode != 64 { - /* - * here, the assembly has failed. - * if its a byte instruction that has - * unaddressable registers, try to - * exchange registers and reissue the - * instruction with the operands renamed. - */ - pp := *p - - unbytereg(&pp.From, &pp.Ft) - unbytereg(&pp.To, &pp.Tt) - - z := int(p.From.Reg) - if p.From.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI { - // TODO(rsc): Use this code for x86-64 too. It has bug fixes not present in the amd64 code base. - // For now, different to keep bit-for-bit compatibility. - if p.Mode == 32 { - breg := byteswapreg(ctxt, &p.To) - if breg != REG_AX { - ctxt.AsmBuf.Put1(0x87) // xchg lhs,bx - asmando(ctxt, p, &p.From, reg[breg]) - subreg(&pp, z, breg) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(0x87) // xchg lhs,bx - asmando(ctxt, p, &p.From, reg[breg]) - } else { - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg lsh,ax - subreg(&pp, z, REG_AX) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg lsh,ax - } - return - } - - if isax(&p.To) || p.To.Type == obj.TYPE_NONE { - // We certainly don't want to exchange - // with AX if the op is MUL or DIV. - ctxt.AsmBuf.Put1(0x87) // xchg lhs,bx - asmando(ctxt, p, &p.From, reg[REG_BX]) - subreg(&pp, z, REG_BX) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(0x87) // xchg lhs,bx - asmando(ctxt, p, &p.From, reg[REG_BX]) - } else { - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg lsh,ax - subreg(&pp, z, REG_AX) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg lsh,ax - } - return - } - - z = int(p.To.Reg) - if p.To.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI { - // TODO(rsc): Use this code for x86-64 too. It has bug fixes not present in the amd64 code base. - // For now, different to keep bit-for-bit compatibility. - if p.Mode == 32 { - breg := byteswapreg(ctxt, &p.From) - if breg != REG_AX { - ctxt.AsmBuf.Put1(0x87) //xchg rhs,bx - asmando(ctxt, p, &p.To, reg[breg]) - subreg(&pp, z, breg) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(0x87) // xchg rhs,bx - asmando(ctxt, p, &p.To, reg[breg]) - } else { - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg rsh,ax - subreg(&pp, z, REG_AX) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg rsh,ax - } - return - } - - if isax(&p.From) { - ctxt.AsmBuf.Put1(0x87) // xchg rhs,bx - asmando(ctxt, p, &p.To, reg[REG_BX]) - subreg(&pp, z, REG_BX) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(0x87) // xchg rhs,bx - asmando(ctxt, p, &p.To, reg[REG_BX]) - } else { - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg rsh,ax - subreg(&pp, z, REG_AX) - doasm(ctxt, &pp) - ctxt.AsmBuf.Put1(byte(0x90 + reg[z])) // xchg rsh,ax - } - return - } - } - - ctxt.Diag("invalid instruction: %v", p) - // ctxt.Diag("doasm: notfound ft=%d tt=%d %v %d %d", p.Ft, p.Tt, p, oclass(ctxt, p, &p.From), oclass(ctxt, p, &p.To)) - return -} - -// byteswapreg returns a byte-addressable register (AX, BX, CX, DX) -// which is not referenced in a. -// If a is empty, it returns BX to account for MULB-like instructions -// that might use DX and AX. -func byteswapreg(ctxt *obj.Link, a *obj.Addr) int { - cand := 1 - canc := cand - canb := canc - cana := canb - - if a.Type == obj.TYPE_NONE { - cand = 0 - cana = cand - } - - if a.Type == obj.TYPE_REG || ((a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Name == obj.NAME_NONE) { - switch a.Reg { - case REG_NONE: - cand = 0 - cana = cand - - case REG_AX, REG_AL, REG_AH: - cana = 0 - - case REG_BX, REG_BL, REG_BH: - canb = 0 - - case REG_CX, REG_CL, REG_CH: - canc = 0 - - case REG_DX, REG_DL, REG_DH: - cand = 0 - } - } - - if a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR { - switch a.Index { - case REG_AX: - cana = 0 - - case REG_BX: - canb = 0 - - case REG_CX: - canc = 0 - - case REG_DX: - cand = 0 - } - } - - if cana != 0 { - return REG_AX - } - if canb != 0 { - return REG_BX - } - if canc != 0 { - return REG_CX - } - if cand != 0 { - return REG_DX - } - - ctxt.Diag("impossible byte register") - log.Fatalf("bad code") - return 0 -} - -func isbadbyte(a *obj.Addr) bool { - return a.Type == obj.TYPE_REG && (REG_BP <= a.Reg && a.Reg <= REG_DI || REG_BPB <= a.Reg && a.Reg <= REG_DIB) -} - -var naclret = []uint8{ - 0x5e, // POPL SI - // 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging - 0x83, - 0xe6, - 0xe0, // ANDL $~31, SI - 0x4c, - 0x01, - 0xfe, // ADDQ R15, SI - 0xff, - 0xe6, // JMP SI -} - -var naclret8 = []uint8{ - 0x5d, // POPL BP - // 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging - 0x83, - 0xe5, - 0xe0, // ANDL $~31, BP - 0xff, - 0xe5, // JMP BP -} - -var naclspfix = []uint8{0x4c, 0x01, 0xfc} // ADDQ R15, SP - -var naclbpfix = []uint8{0x4c, 0x01, 0xfd} // ADDQ R15, BP - -var naclmovs = []uint8{ - 0x89, - 0xf6, // MOVL SI, SI - 0x49, - 0x8d, - 0x34, - 0x37, // LEAQ (R15)(SI*1), SI - 0x89, - 0xff, // MOVL DI, DI - 0x49, - 0x8d, - 0x3c, - 0x3f, // LEAQ (R15)(DI*1), DI -} - -var naclstos = []uint8{ - 0x89, - 0xff, // MOVL DI, DI - 0x49, - 0x8d, - 0x3c, - 0x3f, // LEAQ (R15)(DI*1), DI -} - -func nacltrunc(ctxt *obj.Link, reg int) { - if reg >= REG_R8 { - ctxt.AsmBuf.Put1(0x45) - } - reg = (reg - REG_AX) & 7 - ctxt.AsmBuf.Put2(0x89, byte(3<<6|reg<<3|reg)) -} - -func asmins(ctxt *obj.Link, p *obj.Prog) { - ctxt.AsmBuf.Reset() - ctxt.Asmode = int(p.Mode) - - if ctxt.Headtype == obj.Hnacl && p.Mode == 32 { - switch p.As { - case obj.ARET: - ctxt.AsmBuf.Put(naclret8) - return - - case obj.ACALL, - obj.AJMP: - if p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { - ctxt.AsmBuf.Put3(0x83, byte(0xe0|(p.To.Reg-REG_AX)), 0xe0) - } - - case AINT: - ctxt.AsmBuf.Put1(0xf4) - return - } - } - - if ctxt.Headtype == obj.Hnacl && p.Mode == 64 { - if p.As == AREP { - ctxt.Rep++ - return - } - - if p.As == AREPN { - ctxt.Repn++ - return - } - - if p.As == ALOCK { - ctxt.Lock++ - return - } - - if p.As != ALEAQ && p.As != ALEAL { - if p.From.Index != REG_NONE && p.From.Scale > 0 { - nacltrunc(ctxt, int(p.From.Index)) - } - if p.To.Index != REG_NONE && p.To.Scale > 0 { - nacltrunc(ctxt, int(p.To.Index)) - } - } - - switch p.As { - case obj.ARET: - ctxt.AsmBuf.Put(naclret) - return - - case obj.ACALL, - obj.AJMP: - if p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { - // ANDL $~31, reg - ctxt.AsmBuf.Put3(0x83, byte(0xe0|(p.To.Reg-REG_AX)), 0xe0) - // ADDQ R15, reg - ctxt.AsmBuf.Put3(0x4c, 0x01, byte(0xf8|(p.To.Reg-REG_AX))) - } - - if p.To.Type == obj.TYPE_REG && REG_R8 <= p.To.Reg && p.To.Reg <= REG_R15 { - // ANDL $~31, reg - ctxt.AsmBuf.Put4(0x41, 0x83, byte(0xe0|(p.To.Reg-REG_R8)), 0xe0) - // ADDQ R15, reg - ctxt.AsmBuf.Put3(0x4d, 0x01, byte(0xf8|(p.To.Reg-REG_R8))) - } - - case AINT: - ctxt.AsmBuf.Put1(0xf4) - return - - case ASCASB, - ASCASW, - ASCASL, - ASCASQ, - ASTOSB, - ASTOSW, - ASTOSL, - ASTOSQ: - ctxt.AsmBuf.Put(naclstos) - - case AMOVSB, AMOVSW, AMOVSL, AMOVSQ: - ctxt.AsmBuf.Put(naclmovs) - } - - if ctxt.Rep != 0 { - ctxt.AsmBuf.Put1(0xf3) - ctxt.Rep = 0 - } - - if ctxt.Repn != 0 { - ctxt.AsmBuf.Put1(0xf2) - ctxt.Repn = 0 - } - - if ctxt.Lock != 0 { - ctxt.AsmBuf.Put1(0xf0) - ctxt.Lock = 0 - } - } - - ctxt.Rexflag = 0 - ctxt.Vexflag = 0 - mark := ctxt.AsmBuf.Len() - ctxt.Asmode = int(p.Mode) - doasm(ctxt, p) - if ctxt.Rexflag != 0 && ctxt.Vexflag == 0 { - /* - * as befits the whole approach of the architecture, - * the rex prefix must appear before the first opcode byte - * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but - * before the 0f opcode escape!), or it might be ignored. - * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'. - */ - if p.Mode != 64 { - ctxt.Diag("asmins: illegal in mode %d: %v (%d %d)", p.Mode, p, p.Ft, p.Tt) - } - n := ctxt.AsmBuf.Len() - var np int - for np = mark; np < n; np++ { - c := ctxt.AsmBuf.Peek(np) - if c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26 { - break - } - } - ctxt.AsmBuf.Insert(np, byte(0x40|ctxt.Rexflag)) - } - - n := ctxt.AsmBuf.Len() - for i := len(ctxt.Cursym.R) - 1; i >= 0; i-- { - r := &ctxt.Cursym.R[i] - if int64(r.Off) < p.Pc { - break - } - if ctxt.Rexflag != 0 { - r.Off++ - } - if r.Type == obj.R_PCREL { - if p.Mode == 64 || p.As == obj.AJMP || p.As == obj.ACALL { - // PC-relative addressing is relative to the end of the instruction, - // but the relocations applied by the linker are relative to the end - // of the relocation. Because immediate instruction - // arguments can follow the PC-relative memory reference in the - // instruction encoding, the two may not coincide. In this case, - // adjust addend so that linker can keep relocating relative to the - // end of the relocation. - r.Add -= p.Pc + int64(n) - (int64(r.Off) + int64(r.Siz)) - } else if p.Mode == 32 { - // On 386 PC-relative addressing (for non-call/jmp instructions) - // assumes that the previous instruction loaded the PC of the end - // of that instruction into CX, so the adjustment is relative to - // that. - r.Add += int64(r.Off) - p.Pc + int64(r.Siz) - } - } - if r.Type == obj.R_GOTPCREL && p.Mode == 32 { - // On 386, R_GOTPCREL makes the same assumptions as R_PCREL. - r.Add += int64(r.Off) - p.Pc + int64(r.Siz) - } - - } - - if p.Mode == 64 && ctxt.Headtype == obj.Hnacl && p.As != ACMPL && p.As != ACMPQ && p.To.Type == obj.TYPE_REG { - switch p.To.Reg { - case REG_SP: - ctxt.AsmBuf.Put(naclspfix) - case REG_BP: - ctxt.AsmBuf.Put(naclbpfix) - } - } -} diff --git a/vendor/github.com/google/gops/internal/obj/x86/list6.go b/vendor/github.com/google/gops/internal/obj/x86/list6.go deleted file mode 100644 index 48f2edd5..00000000 --- a/vendor/github.com/google/gops/internal/obj/x86/list6.go +++ /dev/null @@ -1,181 +0,0 @@ -// Inferno utils/6c/list.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6c/list.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package x86 - -import ( - "fmt" - - "github.com/google/gops/internal/obj" -) - -var Register = []string{ - "AL", /* [D_AL] */ - "CL", - "DL", - "BL", - "SPB", - "BPB", - "SIB", - "DIB", - "R8B", - "R9B", - "R10B", - "R11B", - "R12B", - "R13B", - "R14B", - "R15B", - "AX", /* [D_AX] */ - "CX", - "DX", - "BX", - "SP", - "BP", - "SI", - "DI", - "R8", - "R9", - "R10", - "R11", - "R12", - "R13", - "R14", - "R15", - "AH", - "CH", - "DH", - "BH", - "F0", /* [D_F0] */ - "F1", - "F2", - "F3", - "F4", - "F5", - "F6", - "F7", - "M0", - "M1", - "M2", - "M3", - "M4", - "M5", - "M6", - "M7", - "X0", - "X1", - "X2", - "X3", - "X4", - "X5", - "X6", - "X7", - "X8", - "X9", - "X10", - "X11", - "X12", - "X13", - "X14", - "X15", - "Y0", - "Y1", - "Y2", - "Y3", - "Y4", - "Y5", - "Y6", - "Y7", - "Y8", - "Y9", - "Y10", - "Y11", - "Y12", - "Y13", - "Y14", - "Y15", - "CS", /* [D_CS] */ - "SS", - "DS", - "ES", - "FS", - "GS", - "GDTR", /* [D_GDTR] */ - "IDTR", /* [D_IDTR] */ - "LDTR", /* [D_LDTR] */ - "MSW", /* [D_MSW] */ - "TASK", /* [D_TASK] */ - "CR0", /* [D_CR] */ - "CR1", - "CR2", - "CR3", - "CR4", - "CR5", - "CR6", - "CR7", - "CR8", - "CR9", - "CR10", - "CR11", - "CR12", - "CR13", - "CR14", - "CR15", - "DR0", /* [D_DR] */ - "DR1", - "DR2", - "DR3", - "DR4", - "DR5", - "DR6", - "DR7", - "TR0", /* [D_TR] */ - "TR1", - "TR2", - "TR3", - "TR4", - "TR5", - "TR6", - "TR7", - "TLS", /* [D_TLS] */ - "MAXREG", /* [MAXREG] */ -} - -func init() { - obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv) - obj.RegisterOpcode(obj.ABaseAMD64, Anames) -} - -func Rconv(r int) string { - if REG_AL <= r && r-REG_AL < len(Register) { - return Register[r-REG_AL] - } - return fmt.Sprintf("Rgok(%d)", r-obj.RBaseAMD64) -} diff --git a/vendor/github.com/google/gops/internal/obj/x86/obj6.go b/vendor/github.com/google/gops/internal/obj/x86/obj6.go deleted file mode 100644 index aad950bb..00000000 --- a/vendor/github.com/google/gops/internal/obj/x86/obj6.go +++ /dev/null @@ -1,1481 +0,0 @@ -// Inferno utils/6l/pass.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/pass.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package x86 - -import ( - "fmt" - "log" - "math" - "strings" - - "github.com/google/gops/internal/obj" - "github.com/google/gops/internal/sys" -) - -func CanUse1InsnTLS(ctxt *obj.Link) bool { - if isAndroid { - // For android, we use a disgusting hack that assumes - // the thread-local storage slot for g is allocated - // using pthread_key_create with a fixed offset - // (see src/runtime/cgo/gcc_android_amd64.c). - // This makes access to the TLS storage (for g) doable - // with 1 instruction. - return true - } - - if ctxt.Arch.RegSize == 4 { - switch ctxt.Headtype { - case obj.Hlinux, - obj.Hnacl, - obj.Hplan9, - obj.Hwindows, - obj.Hwindowsgui: - return false - } - - return true - } - - switch ctxt.Headtype { - case obj.Hplan9, obj.Hwindows, obj.Hwindowsgui: - return false - case obj.Hlinux: - return !ctxt.Flag_shared - } - - return true -} - -func progedit(ctxt *obj.Link, p *obj.Prog) { - // Maintain information about code generation mode. - if ctxt.Mode == 0 { - ctxt.Mode = ctxt.Arch.RegSize * 8 - } - p.Mode = int8(ctxt.Mode) - - switch p.As { - case AMODE: - if p.From.Type == obj.TYPE_CONST || (p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_NONE) { - switch int(p.From.Offset) { - case 16, 32, 64: - ctxt.Mode = int(p.From.Offset) - } - } - obj.Nopout(p) - } - - // Thread-local storage references use the TLS pseudo-register. - // As a register, TLS refers to the thread-local storage base, and it - // can only be loaded into another register: - // - // MOVQ TLS, AX - // - // An offset from the thread-local storage base is written off(reg)(TLS*1). - // Semantically it is off(reg), but the (TLS*1) annotation marks this as - // indexing from the loaded TLS base. This emits a relocation so that - // if the linker needs to adjust the offset, it can. For example: - // - // MOVQ TLS, AX - // MOVQ 0(AX)(TLS*1), CX // load g into CX - // - // On systems that support direct access to the TLS memory, this - // pair of instructions can be reduced to a direct TLS memory reference: - // - // MOVQ 0(TLS), CX // load g into CX - // - // The 2-instruction and 1-instruction forms correspond to the two code - // sequences for loading a TLS variable in the local exec model given in "ELF - // Handling For Thread-Local Storage". - // - // We apply this rewrite on systems that support the 1-instruction form. - // The decision is made using only the operating system and the -shared flag, - // not the link mode. If some link modes on a particular operating system - // require the 2-instruction form, then all builds for that operating system - // will use the 2-instruction form, so that the link mode decision can be - // delayed to link time. - // - // In this way, all supported systems use identical instructions to - // access TLS, and they are rewritten appropriately first here in - // liblink and then finally using relocations in the linker. - // - // When -shared is passed, we leave the code in the 2-instruction form but - // assemble (and relocate) them in different ways to generate the initial - // exec code sequence. It's a bit of a fluke that this is possible without - // rewriting the instructions more comprehensively, and it only does because - // we only support a single TLS variable (g). - - if CanUse1InsnTLS(ctxt) { - // Reduce 2-instruction sequence to 1-instruction sequence. - // Sequences like - // MOVQ TLS, BX - // ... off(BX)(TLS*1) ... - // become - // NOP - // ... off(TLS) ... - // - // TODO(rsc): Remove the Hsolaris special case. It exists only to - // guarantee we are producing byte-identical binaries as before this code. - // But it should be unnecessary. - if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 && ctxt.Headtype != obj.Hsolaris { - obj.Nopout(p) - } - if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_R15 { - p.From.Reg = REG_TLS - p.From.Scale = 0 - p.From.Index = REG_NONE - } - - if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 { - p.To.Reg = REG_TLS - p.To.Scale = 0 - p.To.Index = REG_NONE - } - } else { - // load_g_cx, below, always inserts the 1-instruction sequence. Rewrite it - // as the 2-instruction sequence if necessary. - // MOVQ 0(TLS), BX - // becomes - // MOVQ TLS, BX - // MOVQ 0(BX)(TLS*1), BX - if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 { - q := obj.Appendp(ctxt, p) - q.As = p.As - q.From = p.From - q.From.Type = obj.TYPE_MEM - q.From.Reg = p.To.Reg - q.From.Index = REG_TLS - q.From.Scale = 2 // TODO: use 1 - q.To = p.To - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_TLS - p.From.Index = REG_NONE - p.From.Offset = 0 - } - } - - // TODO: Remove. - if (ctxt.Headtype == obj.Hwindows || ctxt.Headtype == obj.Hwindowsgui) && p.Mode == 64 || ctxt.Headtype == obj.Hplan9 { - if p.From.Scale == 1 && p.From.Index == REG_TLS { - p.From.Scale = 2 - } - if p.To.Scale == 1 && p.To.Index == REG_TLS { - p.To.Scale = 2 - } - } - - // Rewrite 0 to $0 in 3rd argument to CMPPS etc. - // That's what the tables expect. - switch p.As { - case ACMPPD, ACMPPS, ACMPSD, ACMPSS: - if p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_NONE && p.To.Reg == REG_NONE && p.To.Index == REG_NONE && p.To.Sym == nil { - p.To.Type = obj.TYPE_CONST - } - } - - // Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH. - switch p.As { - case obj.ACALL, obj.AJMP, obj.ARET: - if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - } - - // Rewrite MOVL/MOVQ $XXX(FP/SP) as LEAL/LEAQ. - if p.From.Type == obj.TYPE_ADDR && (ctxt.Arch.Family == sys.AMD64 || p.From.Name != obj.NAME_EXTERN && p.From.Name != obj.NAME_STATIC) { - switch p.As { - case AMOVL: - p.As = ALEAL - p.From.Type = obj.TYPE_MEM - case AMOVQ: - p.As = ALEAQ - p.From.Type = obj.TYPE_MEM - } - } - - if ctxt.Headtype == obj.Hnacl && p.Mode == 64 { - if p.From3 != nil { - nacladdr(ctxt, p, p.From3) - } - nacladdr(ctxt, p, &p.From) - nacladdr(ctxt, p, &p.To) - } - - // Rewrite float constants to values stored in memory. - switch p.As { - // Convert AMOVSS $(0), Xx to AXORPS Xx, Xx - case AMOVSS: - if p.From.Type == obj.TYPE_FCONST { - // f == 0 can't be used here due to -0, so use Float64bits - if f := p.From.Val.(float64); math.Float64bits(f) == 0 { - if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 { - p.As = AXORPS - p.From = p.To - break - } - } - } - fallthrough - - case AFMOVF, - AFADDF, - AFSUBF, - AFSUBRF, - AFMULF, - AFDIVF, - AFDIVRF, - AFCOMF, - AFCOMFP, - AADDSS, - ASUBSS, - AMULSS, - ADIVSS, - ACOMISS, - AUCOMISS: - if p.From.Type == obj.TYPE_FCONST { - f32 := float32(p.From.Val.(float64)) - i32 := math.Float32bits(f32) - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_EXTERN - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Offset = 0 - } - - case AMOVSD: - // Convert AMOVSD $(0), Xx to AXORPS Xx, Xx - if p.From.Type == obj.TYPE_FCONST { - // f == 0 can't be used here due to -0, so use Float64bits - if f := p.From.Val.(float64); math.Float64bits(f) == 0 { - if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 { - p.As = AXORPS - p.From = p.To - break - } - } - } - fallthrough - - case AFMOVD, - AFADDD, - AFSUBD, - AFSUBRD, - AFMULD, - AFDIVD, - AFDIVRD, - AFCOMD, - AFCOMDP, - AADDSD, - ASUBSD, - AMULSD, - ADIVSD, - ACOMISD, - AUCOMISD: - if p.From.Type == obj.TYPE_FCONST { - i64 := math.Float64bits(p.From.Val.(float64)) - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_EXTERN - p.From.Sym = s - p.From.Sym.Set(obj.AttrLocal, true) - p.From.Offset = 0 - } - } - - if ctxt.Flag_dynlink { - rewriteToUseGot(ctxt, p) - } - - if ctxt.Flag_shared && p.Mode == 32 { - rewriteToPcrel(ctxt, p) - } -} - -// Rewrite p, if necessary, to access global data via the global offset table. -func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { - var add, lea, mov obj.As - var reg int16 - if p.Mode == 64 { - add = AADDQ - lea = ALEAQ - mov = AMOVQ - reg = REG_R15 - } else { - add = AADDL - lea = ALEAL - mov = AMOVL - reg = REG_CX - if p.As == ALEAL && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index { - // Special case: clobber the destination register with - // the PC so we don't have to clobber CX. - // The SSA backend depends on CX not being clobbered across LEAL. - // See cmd/compile/internal/ssa/gen/386.rules (search for Flag_shared). - reg = p.To.Reg - } - } - - if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { - // ADUFFxxx $offset - // becomes - // $MOV runtime.duffxxx@GOT, $reg - // $ADD $offset, $reg - // CALL $reg - var sym *obj.LSym - if p.As == obj.ADUFFZERO { - sym = obj.Linklookup(ctxt, "runtime.duffzero", 0) - } else { - sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0) - } - offset := p.To.Offset - p.As = mov - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - p.From.Sym = sym - p.To.Type = obj.TYPE_REG - p.To.Reg = reg - p.To.Offset = 0 - p.To.Sym = nil - p1 := obj.Appendp(ctxt, p) - p1.As = add - p1.From.Type = obj.TYPE_CONST - p1.From.Offset = offset - p1.To.Type = obj.TYPE_REG - p1.To.Reg = reg - p2 := obj.Appendp(ctxt, p1) - p2.As = obj.ACALL - p2.To.Type = obj.TYPE_REG - p2.To.Reg = reg - } - - // We only care about global data: NAME_EXTERN means a global - // symbol in the Go sense, and p.Sym.Local is true for a few - // internally defined symbols. - if p.As == lea && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - // $LEA sym, Rx becomes $MOV $sym, Rx which will be rewritten below - p.As = mov - p.From.Type = obj.TYPE_ADDR - } - if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - // $MOV $sym, Rx becomes $MOV sym@GOT, Rx - // $MOV $sym+, Rx becomes $MOV sym@GOT, Rx; $LEA (Rx), Rx - // On 386 only, more complicated things like PUSHL $sym become $MOV sym@GOT, CX; PUSHL CX - cmplxdest := false - pAs := p.As - var dest obj.Addr - if p.To.Type != obj.TYPE_REG || pAs != mov { - if p.Mode == 64 { - ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p) - } - cmplxdest = true - dest = p.To - p.As = mov - p.To.Type = obj.TYPE_REG - p.To.Reg = reg - p.To.Sym = nil - p.To.Name = obj.NAME_NONE - } - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_GOTREF - q := p - if p.From.Offset != 0 { - q = obj.Appendp(ctxt, p) - q.As = lea - q.From.Type = obj.TYPE_MEM - q.From.Reg = p.To.Reg - q.From.Offset = p.From.Offset - q.To = p.To - p.From.Offset = 0 - } - if cmplxdest { - q = obj.Appendp(ctxt, q) - q.As = pAs - q.To = dest - q.From.Type = obj.TYPE_REG - q.From.Reg = reg - } - } - if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - var source *obj.Addr - // MOVx sym, Ry becomes $MOV sym@GOT, R15; MOVx (R15), Ry - // MOVx Ry, sym becomes $MOV sym@GOT, R15; MOVx Ry, (R15) - // An addition may be inserted between the two MOVs if there is an offset. - if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { - if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) - } - source = &p.From - } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { - source = &p.To - } else { - return - } - if p.As == obj.ACALL { - // When dynlinking on 386, almost any call might end up being a call - // to a PLT, so make sure the GOT pointer is loaded into BX. - // RegTo2 is set on the replacement call insn to stop it being - // processed when it is in turn passed to progedit. - if p.Mode == 64 || (p.To.Sym != nil && p.To.Sym.Local()) || p.RegTo2 != 0 { - return - } - p1 := obj.Appendp(ctxt, p) - p2 := obj.Appendp(ctxt, p1) - - p1.As = ALEAL - p1.From.Type = obj.TYPE_MEM - p1.From.Name = obj.NAME_STATIC - p1.From.Sym = obj.Linklookup(ctxt, "_GLOBAL_OFFSET_TABLE_", 0) - p1.To.Type = obj.TYPE_REG - p1.To.Reg = REG_BX - - p2.As = p.As - p2.Scond = p.Scond - p2.From = p.From - p2.From3 = p.From3 - p2.Reg = p.Reg - p2.To = p.To - // p.To.Type was set to TYPE_BRANCH above, but that makes checkaddr - // in ../pass.go complain, so set it back to TYPE_MEM here, until p2 - // itself gets passed to progedit. - p2.To.Type = obj.TYPE_MEM - p2.RegTo2 = 1 - - obj.Nopout(p) - return - - } - if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ARET || p.As == obj.AJMP { - return - } - if source.Type != obj.TYPE_MEM { - ctxt.Diag("don't know how to handle %v with -dynlink", p) - } - p1 := obj.Appendp(ctxt, p) - p2 := obj.Appendp(ctxt, p1) - - p1.As = mov - p1.From.Type = obj.TYPE_MEM - p1.From.Sym = source.Sym - p1.From.Name = obj.NAME_GOTREF - p1.To.Type = obj.TYPE_REG - p1.To.Reg = reg - - p2.As = p.As - p2.From = p.From - p2.To = p.To - if p.From.Name == obj.NAME_EXTERN { - p2.From.Reg = reg - p2.From.Name = obj.NAME_NONE - p2.From.Sym = nil - } else if p.To.Name == obj.NAME_EXTERN { - p2.To.Reg = reg - p2.To.Name = obj.NAME_NONE - p2.To.Sym = nil - } else { - return - } - obj.Nopout(p) -} - -func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) { - // RegTo2 is set on the instructions we insert here so they don't get - // processed twice. - if p.RegTo2 != 0 { - return - } - if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { - return - } - // Any Prog (aside from the above special cases) with an Addr with Name == - // NAME_EXTERN, NAME_STATIC or NAME_GOTREF has a CALL __x86.get_pc_thunk.XX - // inserted before it. - isName := func(a *obj.Addr) bool { - if a.Sym == nil || (a.Type != obj.TYPE_MEM && a.Type != obj.TYPE_ADDR) || a.Reg != 0 { - return false - } - if a.Sym.Type == obj.STLSBSS { - return false - } - return a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_STATIC || a.Name == obj.NAME_GOTREF - } - - if isName(&p.From) && p.From.Type == obj.TYPE_ADDR { - // Handle things like "MOVL $sym, (SP)" or "PUSHL $sym" by rewriting - // to "MOVL $sym, CX; MOVL CX, (SP)" or "MOVL $sym, CX; PUSHL CX" - // respectively. - if p.To.Type != obj.TYPE_REG { - q := obj.Appendp(ctxt, p) - q.As = p.As - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_CX - q.To = p.To - p.As = AMOVL - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_CX - p.To.Sym = nil - p.To.Name = obj.NAME_NONE - } - } - - if !isName(&p.From) && !isName(&p.To) && (p.From3 == nil || !isName(p.From3)) { - return - } - var dst int16 = REG_CX - if (p.As == ALEAL || p.As == AMOVL) && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index { - dst = p.To.Reg - // Why? See the comment near the top of rewriteToUseGot above. - // AMOVLs might be introduced by the GOT rewrites. - } - q := obj.Appendp(ctxt, p) - q.RegTo2 = 1 - r := obj.Appendp(ctxt, q) - r.RegTo2 = 1 - q.As = obj.ACALL - q.To.Sym = obj.Linklookup(ctxt, "__x86.get_pc_thunk."+strings.ToLower(Rconv(int(dst))), 0) - q.To.Type = obj.TYPE_MEM - q.To.Name = obj.NAME_EXTERN - q.To.Sym.Set(obj.AttrLocal, true) - r.As = p.As - r.Scond = p.Scond - r.From = p.From - r.From3 = p.From3 - r.Reg = p.Reg - r.To = p.To - if isName(&p.From) { - r.From.Reg = dst - } - if isName(&p.To) { - r.To.Reg = dst - } - if p.From3 != nil && isName(p.From3) { - r.From3.Reg = dst - } - obj.Nopout(p) -} - -func nacladdr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - if p.As == ALEAL || p.As == ALEAQ { - return - } - - if a.Reg == REG_BP { - ctxt.Diag("invalid address: %v", p) - return - } - - if a.Reg == REG_TLS { - a.Reg = REG_BP - } - if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE { - switch a.Reg { - // all ok - case REG_BP, REG_SP, REG_R15: - break - - default: - if a.Index != REG_NONE { - ctxt.Diag("invalid address %v", p) - } - a.Index = a.Reg - if a.Index != REG_NONE { - a.Scale = 1 - } - a.Reg = REG_R15 - } - } -} - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - if ctxt.Headtype == obj.Hplan9 && ctxt.Plan9privates == nil { - ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) - } - - ctxt.Cursym = cursym - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - p := cursym.Text - autoffset := int32(p.To.Offset) - if autoffset < 0 { - autoffset = 0 - } - - var bpsize int - if p.Mode == 64 && ctxt.Framepointer_enabled && autoffset > 0 && p.From3.Offset&obj.NOFRAME == 0 { - // Make room for to save a base pointer. If autoffset == 0, - // this might do something special like a tail jump to - // another function, so in that case we omit this. - bpsize = ctxt.Arch.PtrSize - autoffset += int32(bpsize) - p.To.Offset += int64(bpsize) - } else { - bpsize = 0 - } - - textarg := int64(p.To.Val.(int32)) - cursym.Args = int32(textarg) - cursym.Locals = int32(p.To.Offset) - - // TODO(rsc): Remove. - if p.Mode == 32 && cursym.Locals < 0 { - cursym.Locals = 0 - } - - // TODO(rsc): Remove 'p.Mode == 64 &&'. - if p.Mode == 64 && autoffset < obj.StackSmall && p.From3Offset()&obj.NOSPLIT == 0 { - leaf := true - LeafSearch: - for q := p; q != nil; q = q.Link { - switch q.As { - case obj.ACALL: - // Treat common runtime calls that take no arguments - // the same as duffcopy and duffzero. - if !isZeroArgRuntimeCall(q.To.Sym) { - leaf = false - break LeafSearch - } - fallthrough - case obj.ADUFFCOPY, obj.ADUFFZERO: - if autoffset >= obj.StackSmall-8 { - leaf = false - break LeafSearch - } - } - } - - if leaf { - p.From3.Offset |= obj.NOSPLIT - } - } - - if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 { - p = obj.Appendp(ctxt, p) - p = load_g_cx(ctxt, p) // load g into CX - } - - if cursym.Text.From3Offset()&obj.NOSPLIT == 0 { - p = stacksplit(ctxt, p, autoffset, int32(textarg)) // emit split check - } - - if autoffset != 0 { - if autoffset%int32(ctxt.Arch.RegSize) != 0 { - ctxt.Diag("unaligned stack size %d", autoffset) - } - p = obj.Appendp(ctxt, p) - p.As = AADJSP - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autoffset) - p.Spadj = autoffset - } - - deltasp := autoffset - - if bpsize > 0 { - // Save caller's BP - p = obj.Appendp(ctxt, p) - - p.As = AMOVQ - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_BP - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_SP - p.To.Scale = 1 - p.To.Offset = int64(autoffset) - int64(bpsize) - - // Move current frame to BP - p = obj.Appendp(ctxt, p) - - p.As = ALEAQ - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Scale = 1 - p.From.Offset = int64(autoffset) - int64(bpsize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_BP - } - - if cursym.Text.From3Offset()&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOVQ g_panic(CX), BX - // TESTQ BX, BX - // JEQ end - // LEAQ (autoffset+8)(SP), DI - // CMPQ panic_argp(BX), DI - // JNE end - // MOVQ SP, panic_argp(BX) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes. - - p = obj.Appendp(ctxt, p) - - p.As = AMOVQ - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_CX - p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_BX - if ctxt.Headtype == obj.Hnacl && p.Mode == 64 { - p.As = AMOVL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_R15 - p.From.Scale = 1 - p.From.Index = REG_CX - } - if p.Mode == 32 { - p.As = AMOVL - } - - p = obj.Appendp(ctxt, p) - p.As = ATESTQ - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_BX - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_BX - if ctxt.Headtype == obj.Hnacl || p.Mode == 32 { - p.As = ATESTL - } - - p = obj.Appendp(ctxt, p) - p.As = AJEQ - p.To.Type = obj.TYPE_BRANCH - p1 := p - - p = obj.Appendp(ctxt, p) - p.As = ALEAQ - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Offset = int64(autoffset) + int64(ctxt.Arch.RegSize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_DI - if ctxt.Headtype == obj.Hnacl || p.Mode == 32 { - p.As = ALEAL - } - - p = obj.Appendp(ctxt, p) - p.As = ACMPQ - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_BX - p.From.Offset = 0 // Panic.argp - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_DI - if ctxt.Headtype == obj.Hnacl && p.Mode == 64 { - p.As = ACMPL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_R15 - p.From.Scale = 1 - p.From.Index = REG_BX - } - if p.Mode == 32 { - p.As = ACMPL - } - - p = obj.Appendp(ctxt, p) - p.As = AJNE - p.To.Type = obj.TYPE_BRANCH - p2 := p - - p = obj.Appendp(ctxt, p) - p.As = AMOVQ - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SP - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_BX - p.To.Offset = 0 // Panic.argp - if ctxt.Headtype == obj.Hnacl && p.Mode == 64 { - p.As = AMOVL - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_R15 - p.To.Scale = 1 - p.To.Index = REG_BX - } - if p.Mode == 32 { - p.As = AMOVL - } - - p = obj.Appendp(ctxt, p) - p.As = obj.ANOP - p1.Pcond = p - p2.Pcond = p - } - - for ; p != nil; p = p.Link { - pcsize := int(p.Mode) / 8 - switch p.From.Name { - case obj.NAME_AUTO: - p.From.Offset += int64(deltasp) - int64(bpsize) - case obj.NAME_PARAM: - p.From.Offset += int64(deltasp) + int64(pcsize) - } - if p.From3 != nil { - switch p.From3.Name { - case obj.NAME_AUTO: - p.From3.Offset += int64(deltasp) - int64(bpsize) - case obj.NAME_PARAM: - p.From3.Offset += int64(deltasp) + int64(pcsize) - } - } - switch p.To.Name { - case obj.NAME_AUTO: - p.To.Offset += int64(deltasp) - int64(bpsize) - case obj.NAME_PARAM: - p.To.Offset += int64(deltasp) + int64(pcsize) - } - - switch p.As { - default: - continue - - case APUSHL, APUSHFL: - deltasp += 4 - p.Spadj = 4 - continue - - case APUSHQ, APUSHFQ: - deltasp += 8 - p.Spadj = 8 - continue - - case APUSHW, APUSHFW: - deltasp += 2 - p.Spadj = 2 - continue - - case APOPL, APOPFL: - deltasp -= 4 - p.Spadj = -4 - continue - - case APOPQ, APOPFQ: - deltasp -= 8 - p.Spadj = -8 - continue - - case APOPW, APOPFW: - deltasp -= 2 - p.Spadj = -2 - continue - - case obj.ARET: - // do nothing - } - - if autoffset != deltasp { - ctxt.Diag("unbalanced PUSH/POP") - } - - if autoffset != 0 { - if bpsize > 0 { - // Restore caller's BP - p.As = AMOVQ - - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Scale = 1 - p.From.Offset = int64(autoffset) - int64(bpsize) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_BP - p = obj.Appendp(ctxt, p) - } - - p.As = AADJSP - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(-autoffset) - p.Spadj = -autoffset - p = obj.Appendp(ctxt, p) - p.As = obj.ARET - - // If there are instructions following - // this ARET, they come from a branch - // with the same stackframe, so undo - // the cleanup. - p.Spadj = +autoffset - } - - if p.To.Sym != nil { // retjmp - p.As = obj.AJMP - } - } -} - -func isZeroArgRuntimeCall(s *obj.LSym) bool { - if s == nil { - return false - } - switch s.Name { - case "runtime.panicindex", "runtime.panicslice", "runtime.panicdivide": - return true - } - return false -} - -func indir_cx(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - if ctxt.Headtype == obj.Hnacl && p.Mode == 64 { - a.Type = obj.TYPE_MEM - a.Reg = REG_R15 - a.Index = REG_CX - a.Scale = 1 - return - } - - a.Type = obj.TYPE_MEM - a.Reg = REG_CX -} - -// Append code to p to load g into cx. -// Overwrites p with the first instruction (no first appendp). -// Overwriting p is unusual but it lets use this in both the -// prologue (caller must call appendp first) and in the epilogue. -// Returns last new instruction. -func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { - p.As = AMOVQ - if ctxt.Arch.PtrSize == 4 { - p.As = AMOVL - } - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_TLS - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_CX - - next := p.Link - progedit(ctxt, p) - for p.Link != next { - p = p.Link - } - - if p.From.Index == REG_TLS { - p.From.Scale = 2 - } - - return p -} - -// Append code to p to check for stack split. -// Appends to (does not overwrite) p. -// Assumes g is in CX. -// Returns last new instruction. -func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32) *obj.Prog { - cmp := ACMPQ - lea := ALEAQ - mov := AMOVQ - sub := ASUBQ - - if ctxt.Headtype == obj.Hnacl || p.Mode == 32 { - cmp = ACMPL - lea = ALEAL - mov = AMOVL - sub = ASUBL - } - - var q1 *obj.Prog - if framesize <= obj.StackSmall { - // small stack: SP <= stackguard - // CMPQ SP, stackguard - p = obj.Appendp(ctxt, p) - - p.As = cmp - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SP - indir_cx(ctxt, p, &p.To) - p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - } else if framesize <= obj.StackBig { - // large stack: SP-framesize <= stackguard-StackSmall - // LEAQ -xxx(SP), AX - // CMPQ AX, stackguard - p = obj.Appendp(ctxt, p) - - p.As = lea - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Offset = -(int64(framesize) - obj.StackSmall) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = cmp - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_AX - indir_cx(ctxt, p, &p.To) - p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - } else { - // Such a large stack we need to protect against wraparound. - // If SP is close to zero: - // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // - // Preemption sets stackguard to StackPreempt, a very large value. - // That breaks the math above, so we have to check for that explicitly. - // MOVQ stackguard, CX - // CMPQ CX, $StackPreempt - // JEQ label-of-call-to-morestack - // LEAQ StackGuard(SP), AX - // SUBQ CX, AX - // CMPQ AX, $(framesize+(StackGuard-StackSmall)) - - p = obj.Appendp(ctxt, p) - - p.As = mov - indir_cx(ctxt, p, &p.From) - p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0 - if ctxt.Cursym.CFunc() { - p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SI - - p = obj.Appendp(ctxt, p) - p.As = cmp - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SI - p.To.Type = obj.TYPE_CONST - p.To.Offset = obj.StackPreempt - if p.Mode == 32 { - p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) - } - - p = obj.Appendp(ctxt, p) - p.As = AJEQ - p.To.Type = obj.TYPE_BRANCH - q1 = p - - p = obj.Appendp(ctxt, p) - p.As = lea - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Offset = obj.StackGuard - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = sub - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SI - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = cmp - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_AX - p.To.Type = obj.TYPE_CONST - p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) - } - - // common - jls := obj.Appendp(ctxt, p) - jls.As = AJLS - jls.To.Type = obj.TYPE_BRANCH - - var last *obj.Prog - for last = ctxt.Cursym.Text; last.Link != nil; last = last.Link { - } - - // Now we are at the end of the function, but logically - // we are still in function prologue. We need to fix the - // SP data and PCDATA. - spfix := obj.Appendp(ctxt, last) - spfix.As = obj.ANOP - spfix.Spadj = -framesize - - pcdata := obj.Appendp(ctxt, spfix) - pcdata.Lineno = ctxt.Cursym.Text.Lineno - pcdata.Mode = ctxt.Cursym.Text.Mode - pcdata.As = obj.APCDATA - pcdata.From.Type = obj.TYPE_CONST - pcdata.From.Offset = obj.PCDATA_StackMapIndex - pcdata.To.Type = obj.TYPE_CONST - pcdata.To.Offset = -1 // pcdata starts at -1 at function entry - - call := obj.Appendp(ctxt, pcdata) - call.Lineno = ctxt.Cursym.Text.Lineno - call.Mode = ctxt.Cursym.Text.Mode - call.As = obj.ACALL - call.To.Type = obj.TYPE_BRANCH - call.To.Name = obj.NAME_EXTERN - morestack := "runtime.morestack" - switch { - case ctxt.Cursym.CFunc(): - morestack = "runtime.morestackc" - case ctxt.Cursym.Text.From3Offset()&obj.NEEDCTXT == 0: - morestack = "runtime.morestack_noctxt" - } - call.To.Sym = obj.Linklookup(ctxt, morestack, 0) - // When compiling 386 code for dynamic linking, the call needs to be adjusted - // to follow PIC rules. This in turn can insert more instructions, so we need - // to keep track of the start of the call (where the jump will be to) and the - // end (which following instructions are appended to). - callend := call - progedit(ctxt, callend) - for ; callend.Link != nil; callend = callend.Link { - progedit(ctxt, callend.Link) - } - - jmp := obj.Appendp(ctxt, callend) - jmp.As = obj.AJMP - jmp.To.Type = obj.TYPE_BRANCH - jmp.Pcond = ctxt.Cursym.Text.Link - jmp.Spadj = +framesize - - jls.Pcond = call - if q1 != nil { - q1.Pcond = call - } - - return jls -} - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func nofollow(a obj.As) bool { - switch a { - case obj.AJMP, - obj.ARET, - AIRETL, - AIRETQ, - AIRETW, - ARETFL, - ARETFQ, - ARETFW, - obj.AUNDEF: - return true - } - - return false -} - -func pushpop(a obj.As) bool { - switch a { - case APUSHL, - APUSHFL, - APUSHQ, - APUSHFQ, - APUSHW, - APUSHFW, - APOPL, - APOPFL, - APOPQ, - APOPFQ, - APOPW, - APOPFW: - return true - } - - return false -} - -func relinv(a obj.As) obj.As { - switch a { - case AJEQ: - return AJNE - case AJNE: - return AJEQ - case AJLE: - return AJGT - case AJLS: - return AJHI - case AJLT: - return AJGE - case AJMI: - return AJPL - case AJGE: - return AJLT - case AJPL: - return AJMI - case AJGT: - return AJLE - case AJHI: - return AJLS - case AJCS: - return AJCC - case AJCC: - return AJCS - case AJPS: - return AJPC - case AJPC: - return AJPS - case AJOS: - return AJOC - case AJOC: - return AJOS - } - - log.Fatalf("unknown relation: %s", a) - return 0 -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var i int - var a obj.As - -loop: - if p == nil { - return - } - if p.As == obj.AJMP { - q = p.Pcond - if q != nil && q.As != obj.ATEXT { - /* mark instruction as done and continue layout at target of jump */ - p.Mark |= DONE - - p = q - if p.Mark&DONE == 0 { - goto loop - } - } - } - - if p.Mark&DONE != 0 { - /* - * p goes here, but already used it elsewhere. - * copy up to 4 instructions or else branch to other copy. - */ - i = 0 - q = p - for ; i < 4; i, q = i+1, q.Link { - if q == nil { - break - } - if q == *last { - break - } - a = q.As - if a == obj.ANOP { - i-- - continue - } - - if nofollow(a) || pushpop(a) { - break // NOTE(rsc): arm does goto copy - } - if q.Pcond == nil || q.Pcond.Mark&DONE != 0 { - continue - } - if a == obj.ACALL || a == ALOOP { - continue - } - for { - if p.As == obj.ANOP { - p = p.Link - continue - } - - q = obj.Copyp(ctxt, p) - p = p.Link - q.Mark |= DONE - (*last).Link = q - *last = q - if q.As != a || q.Pcond == nil || q.Pcond.Mark&DONE != 0 { - continue - } - - q.As = relinv(q.As) - p = q.Pcond - q.Pcond = q.Link - q.Link = p - xfol(ctxt, q.Link, last) - p = q.Link - if p.Mark&DONE != 0 { - return - } - goto loop - /* */ - } - } - q = ctxt.NewProg() - q.As = obj.AJMP - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - /* emit p */ - p.Mark |= DONE - - (*last).Link = p - *last = p - a = p.As - - /* continue loop with what comes after p */ - if nofollow(a) { - return - } - if p.Pcond != nil && a != obj.ACALL { - /* - * some kind of conditional branch. - * recurse to follow one path. - * continue loop on the other. - */ - q = obj.Brchain(ctxt, p.Pcond) - if q != nil { - p.Pcond = q - } - q = obj.Brchain(ctxt, p.Link) - if q != nil { - p.Link = q - } - if p.From.Type == obj.TYPE_CONST { - if p.From.Offset == 1 { - /* - * expect conditional jump to be taken. - * rewrite so that's the fall-through case. - */ - p.As = relinv(a) - - q = p.Link - p.Link = p.Pcond - p.Pcond = q - } - } else { - q = p.Link - if q.Mark&DONE != 0 { - if a != ALOOP { - p.As = relinv(a) - p.Link = p.Pcond - p.Pcond = q - } - } - } - - xfol(ctxt, p.Link, last) - if p.Pcond.Mark&DONE != 0 { - return - } - p = p.Pcond - goto loop - } - - p = p.Link - goto loop -} - -var unaryDst = map[obj.As]bool{ - ABSWAPL: true, - ABSWAPQ: true, - ACMPXCHG8B: true, - ADECB: true, - ADECL: true, - ADECQ: true, - ADECW: true, - AINCB: true, - AINCL: true, - AINCQ: true, - AINCW: true, - ANEGB: true, - ANEGL: true, - ANEGQ: true, - ANEGW: true, - ANOTB: true, - ANOTL: true, - ANOTQ: true, - ANOTW: true, - APOPL: true, - APOPQ: true, - APOPW: true, - ASETCC: true, - ASETCS: true, - ASETEQ: true, - ASETGE: true, - ASETGT: true, - ASETHI: true, - ASETLE: true, - ASETLS: true, - ASETLT: true, - ASETMI: true, - ASETNE: true, - ASETOC: true, - ASETOS: true, - ASETPC: true, - ASETPL: true, - ASETPS: true, - AFFREE: true, - AFLDENV: true, - AFSAVE: true, - AFSTCW: true, - AFSTENV: true, - AFSTSW: true, - AFXSAVE: true, - AFXSAVE64: true, - ASTMXCSR: true, -} - -var Linkamd64 = obj.LinkArch{ - Arch: sys.ArchAMD64, - Preprocess: preprocess, - Assemble: span6, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, -} - -var Linkamd64p32 = obj.LinkArch{ - Arch: sys.ArchAMD64P32, - Preprocess: preprocess, - Assemble: span6, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, -} - -var Link386 = obj.LinkArch{ - Arch: sys.Arch386, - Preprocess: preprocess, - Assemble: span6, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, -} diff --git a/vendor/github.com/google/gops/internal/obj/zbootstrap.go b/vendor/github.com/google/gops/internal/obj/zbootstrap.go deleted file mode 100644 index 5ddb4e0d..00000000 --- a/vendor/github.com/google/gops/internal/obj/zbootstrap.go +++ /dev/null @@ -1,15 +0,0 @@ -// auto generated by go tool dist - -package obj - -import "runtime" - -const defaultGOROOT = `/Users/jbd/go` -const defaultGO386 = `sse2` -const defaultGOARM = `7` -const defaultGOOS = runtime.GOOS -const defaultGOARCH = runtime.GOARCH -const defaultGO_EXTLINK_ENABLED = `` -const version = `devel +4141054 Thu Nov 3 17:42:01 2016 +0000` -const stackGuardMultiplier = 1 -const goexperiment = `` diff --git a/vendor/github.com/google/gops/internal/objfile/disasm.go b/vendor/github.com/google/gops/internal/objfile/disasm.go deleted file mode 100644 index 8af0c8f8..00000000 --- a/vendor/github.com/google/gops/internal/objfile/disasm.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2014 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 objfile - -import ( - "bufio" - "debug/gosym" - "encoding/binary" - "fmt" - "io" - "regexp" - "sort" - "strings" - "text/tabwriter" - - "golang.org/x/arch/arm/armasm" - "golang.org/x/arch/ppc64/ppc64asm" - "golang.org/x/arch/x86/x86asm" -) - -// Disasm is a disassembler for a given File. -type Disasm struct { - syms []Sym //symbols in file, sorted by address - pcln Liner // pcln table - text []byte // bytes of text segment (actual instructions) - textStart uint64 // start PC of text - textEnd uint64 // end PC of text - goarch string // GOARCH string - disasm disasmFunc // disassembler function for goarch - byteOrder binary.ByteOrder // byte order for goarch -} - -// Disasm returns a disassembler for the file f. -func (f *File) Disasm() (*Disasm, error) { - syms, err := f.Symbols() - if err != nil { - return nil, err - } - - pcln, err := f.PCLineTable() - if err != nil { - return nil, err - } - - textStart, textBytes, err := f.Text() - if err != nil { - return nil, err - } - - goarch := f.GOARCH() - disasm := disasms[goarch] - byteOrder := byteOrders[goarch] - if disasm == nil || byteOrder == nil { - return nil, fmt.Errorf("unsupported architecture") - } - - // Filter out section symbols, overwriting syms in place. - keep := syms[:0] - for _, sym := range syms { - switch sym.Name { - case "runtime.text", "text", "_text", "runtime.etext", "etext", "_etext": - // drop - default: - keep = append(keep, sym) - } - } - syms = keep - d := &Disasm{ - syms: syms, - pcln: pcln, - text: textBytes, - textStart: textStart, - textEnd: textStart + uint64(len(textBytes)), - goarch: goarch, - disasm: disasm, - byteOrder: byteOrder, - } - - return d, nil -} - -// lookup finds the symbol name containing addr. -func (d *Disasm) lookup(addr uint64) (name string, base uint64) { - i := sort.Search(len(d.syms), func(i int) bool { return addr < d.syms[i].Addr }) - if i > 0 { - s := d.syms[i-1] - if s.Addr != 0 && s.Addr <= addr && addr < s.Addr+uint64(s.Size) { - return s.Name, s.Addr - } - } - return "", 0 -} - -// base returns the final element in the path. -// It works on both Windows and Unix paths, -// regardless of host operating system. -func base(path string) string { - path = path[strings.LastIndex(path, "/")+1:] - path = path[strings.LastIndex(path, `\`)+1:] - return path -} - -// Print prints a disassembly of the file to w. -// If filter is non-nil, the disassembly only includes functions with names matching filter. -// The disassembly only includes functions that overlap the range [start, end). -func (d *Disasm) Print(w io.Writer, filter *regexp.Regexp, start, end uint64) { - if start < d.textStart { - start = d.textStart - } - if end > d.textEnd { - end = d.textEnd - } - printed := false - bw := bufio.NewWriter(w) - for _, sym := range d.syms { - symStart := sym.Addr - symEnd := sym.Addr + uint64(sym.Size) - relocs := sym.Relocs - if sym.Code != 'T' && sym.Code != 't' || - symStart < d.textStart || - symEnd <= start || end <= symStart || - filter != nil && !filter.MatchString(sym.Name) { - continue - } - if printed { - fmt.Fprintf(bw, "\n") - } - printed = true - - file, _, _ := d.pcln.PCToLine(sym.Addr) - fmt.Fprintf(bw, "TEXT %s(SB) %s\n", sym.Name, file) - - tw := tabwriter.NewWriter(bw, 1, 8, 1, '\t', 0) - if symEnd > end { - symEnd = end - } - code := d.text[:end-d.textStart] - d.Decode(symStart, symEnd, relocs, func(pc, size uint64, file string, line int, text string) { - i := pc - d.textStart - fmt.Fprintf(tw, "\t%s:%d\t%#x\t", base(file), line, pc) - if size%4 != 0 || d.goarch == "386" || d.goarch == "amd64" { - // Print instruction as bytes. - fmt.Fprintf(tw, "%x", code[i:i+size]) - } else { - // Print instruction as 32-bit words. - for j := uint64(0); j < size; j += 4 { - if j > 0 { - fmt.Fprintf(tw, " ") - } - fmt.Fprintf(tw, "%08x", d.byteOrder.Uint32(code[i+j:])) - } - } - fmt.Fprintf(tw, "\t%s\n", text) - }) - tw.Flush() - } - bw.Flush() -} - -// Decode disassembles the text segment range [start, end), calling f for each instruction. -func (d *Disasm) Decode(start, end uint64, relocs []Reloc, f func(pc, size uint64, file string, line int, text string)) { - if start < d.textStart { - start = d.textStart - } - if end > d.textEnd { - end = d.textEnd - } - code := d.text[:end-d.textStart] - lookup := d.lookup - for pc := start; pc < end; { - i := pc - d.textStart - text, size := d.disasm(code[i:], pc, lookup, d.byteOrder) - file, line, _ := d.pcln.PCToLine(pc) - text += "\t" - first := true - for len(relocs) > 0 && relocs[0].Addr < i+uint64(size) { - if first { - first = false - } else { - text += " " - } - text += relocs[0].Stringer.String(pc - start) - relocs = relocs[1:] - } - f(pc, uint64(size), file, line, text) - pc += uint64(size) - } -} - -type lookupFunc func(addr uint64) (sym string, base uint64) -type disasmFunc func(code []byte, pc uint64, lookup lookupFunc, ord binary.ByteOrder) (text string, size int) - -func disasm_386(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) { - return disasm_x86(code, pc, lookup, 32) -} - -func disasm_amd64(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) { - return disasm_x86(code, pc, lookup, 64) -} - -func disasm_x86(code []byte, pc uint64, lookup lookupFunc, arch int) (string, int) { - inst, err := x86asm.Decode(code, 64) - var text string - size := inst.Len - if err != nil || size == 0 || inst.Op == 0 { - size = 1 - text = "?" - } else { - text = x86asm.GoSyntax(inst, pc, lookup) - } - return text, size -} - -type textReader struct { - code []byte - pc uint64 -} - -func (r textReader) ReadAt(data []byte, off int64) (n int, err error) { - if off < 0 || uint64(off) < r.pc { - return 0, io.EOF - } - d := uint64(off) - r.pc - if d >= uint64(len(r.code)) { - return 0, io.EOF - } - n = copy(data, r.code[d:]) - if n < len(data) { - err = io.ErrUnexpectedEOF - } - return -} - -func disasm_arm(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) { - inst, err := armasm.Decode(code, armasm.ModeARM) - var text string - size := inst.Len - if err != nil || size == 0 || inst.Op == 0 { - size = 4 - text = "?" - } else { - text = armasm.GoSyntax(inst, pc, lookup, textReader{code, pc}) - } - return text, size -} - -func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder) (string, int) { - inst, err := ppc64asm.Decode(code, byteOrder) - var text string - size := inst.Len - if err != nil || size == 0 || inst.Op == 0 { - size = 4 - text = "?" - } else { - text = ppc64asm.GoSyntax(inst, pc, lookup) - } - return text, size -} - -var disasms = map[string]disasmFunc{ - "386": disasm_386, - "amd64": disasm_amd64, - "arm": disasm_arm, - "ppc64": disasm_ppc64, - "ppc64le": disasm_ppc64, -} - -var byteOrders = map[string]binary.ByteOrder{ - "386": binary.LittleEndian, - "amd64": binary.LittleEndian, - "arm": binary.LittleEndian, - "ppc64": binary.BigEndian, - "ppc64le": binary.LittleEndian, - "s390x": binary.BigEndian, -} - -type Liner interface { - // Given a pc, returns the corresponding file, line, and function data. - // If unknown, returns "",0,nil. - PCToLine(uint64) (string, int, *gosym.Func) -} diff --git a/vendor/github.com/google/gops/internal/objfile/elf.go b/vendor/github.com/google/gops/internal/objfile/elf.go deleted file mode 100644 index 4ab7e6de..00000000 --- a/vendor/github.com/google/gops/internal/objfile/elf.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 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. - -// Parsing of ELF executables (Linux, FreeBSD, and so on). - -package objfile - -import ( - "debug/dwarf" - "debug/elf" - "encoding/binary" - "fmt" - "os" -) - -type elfFile struct { - elf *elf.File -} - -func openElf(r *os.File) (rawFile, error) { - f, err := elf.NewFile(r) - if err != nil { - return nil, err - } - return &elfFile{f}, nil -} - -func (f *elfFile) symbols() ([]Sym, error) { - elfSyms, err := f.elf.Symbols() - if err != nil { - return nil, err - } - - var syms []Sym - for _, s := range elfSyms { - sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'} - switch s.Section { - case elf.SHN_UNDEF: - sym.Code = 'U' - case elf.SHN_COMMON: - sym.Code = 'B' - default: - i := int(s.Section) - if i < 0 || i >= len(f.elf.Sections) { - break - } - sect := f.elf.Sections[i] - switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) { - case elf.SHF_ALLOC | elf.SHF_EXECINSTR: - sym.Code = 'T' - case elf.SHF_ALLOC: - sym.Code = 'R' - case elf.SHF_ALLOC | elf.SHF_WRITE: - sym.Code = 'D' - } - } - if elf.ST_BIND(s.Info) == elf.STB_LOCAL { - sym.Code += 'a' - 'A' - } - syms = append(syms, sym) - } - - return syms, nil -} - -func (f *elfFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) { - if sect := f.elf.Section(".text"); sect != nil { - textStart = sect.Addr - } - if sect := f.elf.Section(".gosymtab"); sect != nil { - if symtab, err = sect.Data(); err != nil { - return 0, nil, nil, err - } - } - if sect := f.elf.Section(".gopclntab"); sect != nil { - if pclntab, err = sect.Data(); err != nil { - return 0, nil, nil, err - } - } - return textStart, symtab, pclntab, nil -} - -func (f *elfFile) text() (textStart uint64, text []byte, err error) { - sect := f.elf.Section(".text") - if sect == nil { - return 0, nil, fmt.Errorf("text section not found") - } - textStart = sect.Addr - text, err = sect.Data() - return -} - -func (f *elfFile) goarch() string { - switch f.elf.Machine { - case elf.EM_386: - return "386" - case elf.EM_X86_64: - return "amd64" - case elf.EM_ARM: - return "arm" - case elf.EM_PPC64: - if f.elf.ByteOrder == binary.LittleEndian { - return "ppc64le" - } - return "ppc64" - case elf.EM_S390: - return "s390x" - } - return "" -} - -func (f *elfFile) loadAddress() (uint64, error) { - for _, p := range f.elf.Progs { - if p.Type == elf.PT_LOAD { - return p.Vaddr, nil - } - } - return 0, fmt.Errorf("unknown load address") -} - -func (f *elfFile) dwarf() (*dwarf.Data, error) { - return f.elf.DWARF() -} diff --git a/vendor/github.com/google/gops/internal/objfile/goobj.go b/vendor/github.com/google/gops/internal/objfile/goobj.go deleted file mode 100644 index 5a8ec53d..00000000 --- a/vendor/github.com/google/gops/internal/objfile/goobj.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2013 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. - -// Parsing of Go intermediate object files and archives. - -package objfile - -/* - - -import ( - "debug/dwarf" - "debug/gosym" - "errors" - "fmt" - "os" - - "github.com/google/gops/internal/sys" - - "github.com/google/gops/internal/goobj" -) - -type goobjFile struct { - goobj *goobj.Package - f *os.File // the underlying .o or .a file -} - -func openGoobj(r *os.File) (rawFile, error) { - f, err := goobj.Parse(r, `""`) - if err != nil { - return nil, err - } - return &goobjFile{goobj: f, f: r}, nil -} - -func goobjName(id goobj.SymID) string { - if id.Version == 0 { - return id.Name - } - return fmt.Sprintf("%s<%d>", id.Name, id.Version) -} - -func (f *goobjFile) symbols() ([]Sym, error) { - seen := make(map[goobj.SymID]bool) - - var syms []Sym - for _, s := range f.goobj.Syms { - seen[s.SymID] = true - sym := Sym{Addr: uint64(s.Data.Offset), Name: goobjName(s.SymID), Size: int64(s.Size), Type: s.Type.Name, Code: '?'} - switch s.Kind { - case goobj.STEXT, goobj.SELFRXSECT: - sym.Code = 'T' - case goobj.STYPE, goobj.SSTRING, goobj.SGOSTRING, goobj.SGOFUNC, goobj.SRODATA, goobj.SFUNCTAB, goobj.STYPELINK, goobj.SITABLINK, goobj.SSYMTAB, goobj.SPCLNTAB, goobj.SELFROSECT: - sym.Code = 'R' - case goobj.SMACHOPLT, goobj.SELFSECT, goobj.SMACHO, goobj.SMACHOGOT, goobj.SNOPTRDATA, goobj.SINITARR, goobj.SDATA, goobj.SWINDOWS: - sym.Code = 'D' - case goobj.SBSS, goobj.SNOPTRBSS, goobj.STLSBSS: - sym.Code = 'B' - case goobj.SXREF, goobj.SMACHOSYMSTR, goobj.SMACHOSYMTAB, goobj.SMACHOINDIRECTPLT, goobj.SMACHOINDIRECTGOT, goobj.SFILE, goobj.SFILEPATH, goobj.SCONST, goobj.SDYNIMPORT, goobj.SHOSTOBJ: - sym.Code = 'X' // should not see - } - if s.Version != 0 { - sym.Code += 'a' - 'A' - } - for i, r := range s.Reloc { - sym.Relocs = append(sym.Relocs, Reloc{Addr: uint64(s.Data.Offset) + uint64(r.Offset), Size: uint64(r.Size), Stringer: &s.Reloc[i]}) - } - syms = append(syms, sym) - } - - for _, s := range f.goobj.Syms { - for _, r := range s.Reloc { - if !seen[r.Sym] { - seen[r.Sym] = true - sym := Sym{Name: goobjName(r.Sym), Code: 'U'} - if s.Version != 0 { - // should not happen but handle anyway - sym.Code = 'u' - } - syms = append(syms, sym) - } - } - } - - return syms, nil -} - -func (f *goobjFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) { - // Should never be called. We implement Liner below, callers - // should use that instead. - return 0, nil, nil, fmt.Errorf("pcln not available in go object file") -} - -// Find returns the file name, line, and function data for the given pc. -// Returns "",0,nil if unknown. -// This function implements the Liner interface in preference to pcln() above. -func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) { - // TODO: this is really inefficient. Binary search? Memoize last result? - var arch *sys.Arch - for _, a := range sys.Archs { - if a.Name == f.goobj.Arch { - arch = a - break - } - } - if arch == nil { - return "", 0, nil - } - for _, s := range f.goobj.Syms { - if pc < uint64(s.Data.Offset) || pc >= uint64(s.Data.Offset+s.Data.Size) { - continue - } - if s.Func == nil { - return "", 0, nil - } - pcfile := make([]byte, s.Func.PCFile.Size) - _, err := f.f.ReadAt(pcfile, s.Func.PCFile.Offset) - if err != nil { - return "", 0, nil - } - fileID := gosym.PCValue(pcfile, pc-uint64(s.Data.Offset), arch.MinLC) - fileName := s.Func.File[fileID] - pcline := make([]byte, s.Func.PCLine.Size) - _, err = f.f.ReadAt(pcline, s.Func.PCLine.Offset) - if err != nil { - return "", 0, nil - } - line := gosym.PCValue(pcline, pc-uint64(s.Data.Offset), arch.MinLC) - // Note: we provide only the name in the Func structure. - // We could provide more if needed. - return fileName, line, &gosym.Func{Sym: &gosym.Sym{Name: s.Name}} - } - return "", 0, nil -} - -// We treat the whole object file as the text section. -func (f *goobjFile) text() (textStart uint64, text []byte, err error) { - var info os.FileInfo - info, err = f.f.Stat() - if err != nil { - return - } - text = make([]byte, info.Size()) - _, err = f.f.ReadAt(text, 0) - return -} - -func (f *goobjFile) goarch() string { - return f.goobj.Arch -} - -func (f *goobjFile) loadAddress() (uint64, error) { - return 0, fmt.Errorf("unknown load address") -} - -func (f *goobjFile) dwarf() (*dwarf.Data, error) { - return nil, errors.New("no DWARF data in go object file") -} -*/ diff --git a/vendor/github.com/google/gops/internal/objfile/macho.go b/vendor/github.com/google/gops/internal/objfile/macho.go deleted file mode 100644 index 1d22a09b..00000000 --- a/vendor/github.com/google/gops/internal/objfile/macho.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2013 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. - -// Parsing of Mach-O executables (OS X). - -package objfile - -import ( - "debug/dwarf" - "debug/macho" - "fmt" - "os" - "sort" -) - -const stabTypeMask = 0xe0 - -type machoFile struct { - macho *macho.File -} - -func openMacho(r *os.File) (rawFile, error) { - f, err := macho.NewFile(r) - if err != nil { - return nil, err - } - return &machoFile{f}, nil -} - -func (f *machoFile) symbols() ([]Sym, error) { - if f.macho.Symtab == nil { - return nil, fmt.Errorf("missing symbol table") - } - - // Build sorted list of addresses of all symbols. - // We infer the size of a symbol by looking at where the next symbol begins. - var addrs []uint64 - for _, s := range f.macho.Symtab.Syms { - // Skip stab debug info. - if s.Type&stabTypeMask == 0 { - addrs = append(addrs, s.Value) - } - } - sort.Sort(uint64s(addrs)) - - var syms []Sym - for _, s := range f.macho.Symtab.Syms { - if s.Type&stabTypeMask != 0 { - // Skip stab debug info. - continue - } - sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'} - i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value }) - if i < len(addrs) { - sym.Size = int64(addrs[i] - s.Value) - } - if s.Sect == 0 { - sym.Code = 'U' - } else if int(s.Sect) <= len(f.macho.Sections) { - sect := f.macho.Sections[s.Sect-1] - switch sect.Seg { - case "__TEXT": - sym.Code = 'R' - case "__DATA": - sym.Code = 'D' - } - switch sect.Seg + " " + sect.Name { - case "__TEXT __text": - sym.Code = 'T' - case "__DATA __bss", "__DATA __noptrbss": - sym.Code = 'B' - } - } - syms = append(syms, sym) - } - - return syms, nil -} - -func (f *machoFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) { - if sect := f.macho.Section("__text"); sect != nil { - textStart = sect.Addr - } - if sect := f.macho.Section("__gosymtab"); sect != nil { - if symtab, err = sect.Data(); err != nil { - return 0, nil, nil, err - } - } - if sect := f.macho.Section("__gopclntab"); sect != nil { - if pclntab, err = sect.Data(); err != nil { - return 0, nil, nil, err - } - } - return textStart, symtab, pclntab, nil -} - -func (f *machoFile) text() (textStart uint64, text []byte, err error) { - sect := f.macho.Section("__text") - if sect == nil { - return 0, nil, fmt.Errorf("text section not found") - } - textStart = sect.Addr - text, err = sect.Data() - return -} - -func (f *machoFile) goarch() string { - switch f.macho.Cpu { - case macho.Cpu386: - return "386" - case macho.CpuAmd64: - return "amd64" - case macho.CpuArm: - return "arm" - case macho.CpuPpc64: - return "ppc64" - } - return "" -} - -type uint64s []uint64 - -func (x uint64s) Len() int { return len(x) } -func (x uint64s) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x uint64s) Less(i, j int) bool { return x[i] < x[j] } - -func (f *machoFile) loadAddress() (uint64, error) { - return 0, fmt.Errorf("unknown load address") -} - -func (f *machoFile) dwarf() (*dwarf.Data, error) { - return f.macho.DWARF() -} diff --git a/vendor/github.com/google/gops/internal/objfile/objfile.go b/vendor/github.com/google/gops/internal/objfile/objfile.go deleted file mode 100644 index a884a20d..00000000 --- a/vendor/github.com/google/gops/internal/objfile/objfile.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2014 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 objfile implements portable access to OS-specific executable files. -package objfile - -import ( - "debug/dwarf" - "debug/gosym" - "fmt" - "os" - "sort" -) - -type rawFile interface { - symbols() (syms []Sym, err error) - pcln() (textStart uint64, symtab, pclntab []byte, err error) - text() (textStart uint64, text []byte, err error) - goarch() string - loadAddress() (uint64, error) - dwarf() (*dwarf.Data, error) -} - -// A File is an opened executable file. -type File struct { - r *os.File - raw rawFile -} - -// A Sym is a symbol defined in an executable file. -type Sym struct { - Name string // symbol name - Addr uint64 // virtual address of symbol - Size int64 // size in bytes - Code rune // nm code (T for text, D for data, and so on) - Type string // XXX? - Relocs []Reloc // in increasing Addr order -} - -type Reloc struct { - Addr uint64 // Address of first byte that reloc applies to. - Size uint64 // Number of bytes - Stringer RelocStringer -} - -type RelocStringer interface { - // insnOffset is the offset of the instruction containing the relocation - // from the start of the symbol containing the relocation. - String(insnOffset uint64) string -} - -var openers = []func(*os.File) (rawFile, error){ - openElf, - // openGoobj, // TODO(jbd): Bring it back when 1.8 is popular. - openMacho, - openPE, - openPlan9, -} - -// Open opens the named file. -// The caller must call f.Close when the file is no longer needed. -func Open(name string) (*File, error) { - r, err := os.Open(name) - if err != nil { - return nil, err - } - for _, try := range openers { - if raw, err := try(r); err == nil { - return &File{r, raw}, nil - } - } - r.Close() - return nil, fmt.Errorf("open %s: unrecognized object file", name) -} - -func (f *File) Close() error { - return f.r.Close() -} - -func (f *File) Symbols() ([]Sym, error) { - syms, err := f.raw.symbols() - if err != nil { - return nil, err - } - sort.Sort(byAddr(syms)) - return syms, nil -} - -type byAddr []Sym - -func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr } -func (x byAddr) Len() int { return len(x) } -func (x byAddr) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (f *File) PCLineTable() (Liner, error) { - // If the raw file implements Liner directly, use that. - // Currently, only Go intermediate objects and archives (goobj) use this path. - if pcln, ok := f.raw.(Liner); ok { - return pcln, nil - } - // Otherwise, read the pcln tables and build a Liner out of that. - textStart, symtab, pclntab, err := f.raw.pcln() - if err != nil { - return nil, err - } - return gosym.NewTable(symtab, gosym.NewLineTable(pclntab, textStart)) -} - -func (f *File) Text() (uint64, []byte, error) { - return f.raw.text() -} - -func (f *File) GOARCH() string { - return f.raw.goarch() -} - -// LoadAddress returns the expected load address of the file. -// This differs from the actual load address for a position-independent -// executable. -func (f *File) LoadAddress() (uint64, error) { - return f.raw.loadAddress() -} - -// DWARF returns DWARF debug data for the file, if any. -// This is for cmd/pprof to locate cgo functions. -func (f *File) DWARF() (*dwarf.Data, error) { - return f.raw.dwarf() -} diff --git a/vendor/github.com/google/gops/internal/objfile/pe.go b/vendor/github.com/google/gops/internal/objfile/pe.go deleted file mode 100644 index 46b23172..00000000 --- a/vendor/github.com/google/gops/internal/objfile/pe.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2013 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. - -// Parsing of PE executables (Microsoft Windows). - -package objfile - -import ( - "debug/dwarf" - "debug/pe" - "fmt" - "os" - "sort" -) - -type peFile struct { - pe *pe.File -} - -func openPE(r *os.File) (rawFile, error) { - f, err := pe.NewFile(r) - if err != nil { - return nil, err - } - switch f.OptionalHeader.(type) { - case *pe.OptionalHeader32, *pe.OptionalHeader64: - // ok - default: - return nil, fmt.Errorf("unrecognized PE format") - } - return &peFile{f}, nil -} - -func (f *peFile) symbols() ([]Sym, error) { - // Build sorted list of addresses of all symbols. - // We infer the size of a symbol by looking at where the next symbol begins. - var addrs []uint64 - - var imageBase uint64 - switch oh := f.pe.OptionalHeader.(type) { - case *pe.OptionalHeader32: - imageBase = uint64(oh.ImageBase) - case *pe.OptionalHeader64: - imageBase = oh.ImageBase - } - - var syms []Sym - for _, s := range f.pe.Symbols { - const ( - N_UNDEF = 0 // An undefined (extern) symbol - N_ABS = -1 // An absolute symbol (e_value is a constant, not an address) - N_DEBUG = -2 // A debugging symbol - ) - sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'} - switch s.SectionNumber { - case N_UNDEF: - sym.Code = 'U' - case N_ABS: - sym.Code = 'C' - case N_DEBUG: - sym.Code = '?' - default: - if s.SectionNumber < 0 || len(f.pe.Sections) < int(s.SectionNumber) { - return nil, fmt.Errorf("invalid section number in symbol table") - } - sect := f.pe.Sections[s.SectionNumber-1] - const ( - text = 0x20 - data = 0x40 - bss = 0x80 - permW = 0x80000000 - ) - ch := sect.Characteristics - switch { - case ch&text != 0: - sym.Code = 'T' - case ch&data != 0: - if ch&permW == 0 { - sym.Code = 'R' - } else { - sym.Code = 'D' - } - case ch&bss != 0: - sym.Code = 'B' - } - sym.Addr += imageBase + uint64(sect.VirtualAddress) - } - syms = append(syms, sym) - addrs = append(addrs, sym.Addr) - } - - sort.Sort(uint64s(addrs)) - for i := range syms { - j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr }) - if j < len(addrs) { - syms[i].Size = int64(addrs[j] - syms[i].Addr) - } - } - - return syms, nil -} - -func (f *peFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) { - var imageBase uint64 - switch oh := f.pe.OptionalHeader.(type) { - case *pe.OptionalHeader32: - imageBase = uint64(oh.ImageBase) - case *pe.OptionalHeader64: - imageBase = oh.ImageBase - default: - return 0, nil, nil, fmt.Errorf("pe file format not recognized") - } - if sect := f.pe.Section(".text"); sect != nil { - textStart = imageBase + uint64(sect.VirtualAddress) - } - if pclntab, err = loadPETable(f.pe, "runtime.pclntab", "runtime.epclntab"); err != nil { - // We didn't find the symbols, so look for the names used in 1.3 and earlier. - // TODO: Remove code looking for the old symbols when we no longer care about 1.3. - var err2 error - if pclntab, err2 = loadPETable(f.pe, "pclntab", "epclntab"); err2 != nil { - return 0, nil, nil, err - } - } - if symtab, err = loadPETable(f.pe, "runtime.symtab", "runtime.esymtab"); err != nil { - // Same as above. - var err2 error - if symtab, err2 = loadPETable(f.pe, "symtab", "esymtab"); err2 != nil { - return 0, nil, nil, err - } - } - return textStart, symtab, pclntab, nil -} - -func (f *peFile) text() (textStart uint64, text []byte, err error) { - var imageBase uint64 - switch oh := f.pe.OptionalHeader.(type) { - case *pe.OptionalHeader32: - imageBase = uint64(oh.ImageBase) - case *pe.OptionalHeader64: - imageBase = oh.ImageBase - default: - return 0, nil, fmt.Errorf("pe file format not recognized") - } - sect := f.pe.Section(".text") - if sect == nil { - return 0, nil, fmt.Errorf("text section not found") - } - textStart = imageBase + uint64(sect.VirtualAddress) - text, err = sect.Data() - return -} - -func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) { - for _, s := range f.Symbols { - if s.Name != name { - continue - } - if s.SectionNumber <= 0 { - return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber) - } - if len(f.Sections) < int(s.SectionNumber) { - return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections)) - } - return s, nil - } - return nil, fmt.Errorf("no %s symbol found", name) -} - -func loadPETable(f *pe.File, sname, ename string) ([]byte, error) { - ssym, err := findPESymbol(f, sname) - if err != nil { - return nil, err - } - esym, err := findPESymbol(f, ename) - if err != nil { - return nil, err - } - if ssym.SectionNumber != esym.SectionNumber { - return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename) - } - sect := f.Sections[ssym.SectionNumber-1] - data, err := sect.Data() - if err != nil { - return nil, err - } - return data[ssym.Value:esym.Value], nil -} - -func (f *peFile) goarch() string { - // Not sure how to get the info we want from PE header. - // Look in symbol table for telltale rt0 symbol. - if _, err := findPESymbol(f.pe, "_rt0_386_windows"); err == nil { - return "386" - } - if _, err := findPESymbol(f.pe, "_rt0_amd64_windows"); err == nil { - return "amd64" - } - return "" -} - -func (f *peFile) loadAddress() (uint64, error) { - return 0, fmt.Errorf("unknown load address") -} - -func (f *peFile) dwarf() (*dwarf.Data, error) { - return f.pe.DWARF() -} diff --git a/vendor/github.com/google/gops/internal/objfile/plan9obj.go b/vendor/github.com/google/gops/internal/objfile/plan9obj.go deleted file mode 100644 index 3e34f65a..00000000 --- a/vendor/github.com/google/gops/internal/objfile/plan9obj.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2014 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. - -// Parsing of Plan 9 a.out executables. - -package objfile - -import ( - "debug/dwarf" - "debug/plan9obj" - "errors" - "fmt" - "os" - "sort" -) - -var validSymType = map[rune]bool{ - 'T': true, - 't': true, - 'D': true, - 'd': true, - 'B': true, - 'b': true, -} - -type plan9File struct { - plan9 *plan9obj.File -} - -func openPlan9(r *os.File) (rawFile, error) { - f, err := plan9obj.NewFile(r) - if err != nil { - return nil, err - } - return &plan9File{f}, nil -} - -func (f *plan9File) symbols() ([]Sym, error) { - plan9Syms, err := f.plan9.Symbols() - if err != nil { - return nil, err - } - - // Build sorted list of addresses of all symbols. - // We infer the size of a symbol by looking at where the next symbol begins. - var addrs []uint64 - for _, s := range plan9Syms { - if !validSymType[s.Type] { - continue - } - addrs = append(addrs, s.Value) - } - sort.Sort(uint64s(addrs)) - - var syms []Sym - - for _, s := range plan9Syms { - if !validSymType[s.Type] { - continue - } - sym := Sym{Addr: s.Value, Name: s.Name, Code: s.Type} - i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value }) - if i < len(addrs) { - sym.Size = int64(addrs[i] - s.Value) - } - syms = append(syms, sym) - } - - return syms, nil -} - -func (f *plan9File) pcln() (textStart uint64, symtab, pclntab []byte, err error) { - textStart = f.plan9.LoadAddress + f.plan9.HdrSize - if pclntab, err = loadPlan9Table(f.plan9, "runtime.pclntab", "runtime.epclntab"); err != nil { - // We didn't find the symbols, so look for the names used in 1.3 and earlier. - // TODO: Remove code looking for the old symbols when we no longer care about 1.3. - var err2 error - if pclntab, err2 = loadPlan9Table(f.plan9, "pclntab", "epclntab"); err2 != nil { - return 0, nil, nil, err - } - } - if symtab, err = loadPlan9Table(f.plan9, "runtime.symtab", "runtime.esymtab"); err != nil { - // Same as above. - var err2 error - if symtab, err2 = loadPlan9Table(f.plan9, "symtab", "esymtab"); err2 != nil { - return 0, nil, nil, err - } - } - return textStart, symtab, pclntab, nil -} - -func (f *plan9File) text() (textStart uint64, text []byte, err error) { - sect := f.plan9.Section("text") - if sect == nil { - return 0, nil, fmt.Errorf("text section not found") - } - textStart = f.plan9.LoadAddress + f.plan9.HdrSize - text, err = sect.Data() - return -} - -func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) { - syms, err := f.Symbols() - if err != nil { - return nil, err - } - for _, s := range syms { - if s.Name != name { - continue - } - return &s, nil - } - return nil, fmt.Errorf("no %s symbol found", name) -} - -func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) { - ssym, err := findPlan9Symbol(f, sname) - if err != nil { - return nil, err - } - esym, err := findPlan9Symbol(f, ename) - if err != nil { - return nil, err - } - sect := f.Section("text") - if sect == nil { - return nil, err - } - data, err := sect.Data() - if err != nil { - return nil, err - } - textStart := f.LoadAddress + f.HdrSize - return data[ssym.Value-textStart : esym.Value-textStart], nil -} - -func (f *plan9File) goarch() string { - switch f.plan9.Magic { - case plan9obj.Magic386: - return "386" - case plan9obj.MagicAMD64: - return "amd64" - case plan9obj.MagicARM: - return "arm" - } - return "" -} - -func (f *plan9File) loadAddress() (uint64, error) { - return 0, fmt.Errorf("unknown load address") -} - -func (f *plan9File) dwarf() (*dwarf.Data, error) { - return nil, errors.New("no DWARF data in Plan 9 file") -} diff --git a/vendor/github.com/google/gops/internal/sys/arch.go b/vendor/github.com/google/gops/internal/sys/arch.go deleted file mode 100644 index 7033f3fb..00000000 --- a/vendor/github.com/google/gops/internal/sys/arch.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2016 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 sys - -import "encoding/binary" - -// ArchFamily represents a family of one or more related architectures. -// For example, amd64 and amd64p32 are both members of the AMD64 family, -// and ppc64 and ppc64le are both members of the PPC64 family. -type ArchFamily byte - -const ( - AMD64 ArchFamily = iota - ARM - ARM64 - I386 - MIPS64 - PPC64 - S390X -) - -// Arch represents an individual architecture. -type Arch struct { - Name string - Family ArchFamily - - ByteOrder binary.ByteOrder - - IntSize int - PtrSize int - RegSize int - - // MinLC is the minimum length of an instruction code. - MinLC int -} - -// InFamily reports whether a is a member of any of the specified -// architecture families. -func (a *Arch) InFamily(xs ...ArchFamily) bool { - for _, x := range xs { - if a.Family == x { - return true - } - } - return false -} - -var Arch386 = &Arch{ - Name: "386", - Family: I386, - ByteOrder: binary.LittleEndian, - IntSize: 4, - PtrSize: 4, - RegSize: 4, - MinLC: 1, -} - -var ArchAMD64 = &Arch{ - Name: "amd64", - Family: AMD64, - ByteOrder: binary.LittleEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 1, -} - -var ArchAMD64P32 = &Arch{ - Name: "amd64p32", - Family: AMD64, - ByteOrder: binary.LittleEndian, - IntSize: 4, - PtrSize: 4, - RegSize: 8, - MinLC: 1, -} - -var ArchARM = &Arch{ - Name: "arm", - Family: ARM, - ByteOrder: binary.LittleEndian, - IntSize: 4, - PtrSize: 4, - RegSize: 4, - MinLC: 4, -} - -var ArchARM64 = &Arch{ - Name: "arm64", - Family: ARM64, - ByteOrder: binary.LittleEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 4, -} - -var ArchMIPS64 = &Arch{ - Name: "mips64", - Family: MIPS64, - ByteOrder: binary.BigEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 4, -} - -var ArchMIPS64LE = &Arch{ - Name: "mips64le", - Family: MIPS64, - ByteOrder: binary.LittleEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 4, -} - -var ArchPPC64 = &Arch{ - Name: "ppc64", - Family: PPC64, - ByteOrder: binary.BigEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 4, -} - -var ArchPPC64LE = &Arch{ - Name: "ppc64le", - Family: PPC64, - ByteOrder: binary.LittleEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 4, -} - -var ArchS390X = &Arch{ - Name: "s390x", - Family: S390X, - ByteOrder: binary.BigEndian, - IntSize: 8, - PtrSize: 8, - RegSize: 8, - MinLC: 2, -} - -var Archs = [...]*Arch{ - Arch386, - ArchAMD64, - ArchAMD64P32, - ArchARM, - ArchARM64, - ArchMIPS64, - ArchMIPS64LE, - ArchPPC64, - ArchPPC64LE, - ArchS390X, -} -- cgit v1.2.3