From c7759f4edbcc0cb827689d037157aa1d14521f4b Mon Sep 17 00:00:00 2001
From: Vorapol Rinsatitnon
-This is the reference manual for the Go programming language as it was for
-language version 1.17, in October 2021, before the introduction of generics.
-It is provided for historical interest.
-The current reference manual can be found here.
-For more information and other documents, see go.dev.
-
-Go is a general-purpose language designed with systems programming
-in mind. It is strongly typed and garbage-collected and has explicit
-support for concurrent programming. Programs are constructed from
-packages, whose properties allow efficient management of
-dependencies.
-
-The grammar is compact and simple to parse, allowing for easy analysis
-by automatic tools such as integrated development environments.
-
-The syntax is specified using Extended Backus-Naur Form (EBNF):
-
-Productions are expressions constructed from terms and the following
-operators, in increasing precedence:
-
-Lower-case production names are used to identify lexical tokens.
-Non-terminals are in CamelCase. Lexical tokens are enclosed in
-double quotes
-The form
-Source code is Unicode text encoded in
-UTF-8. The text is not
-canonicalized, so a single accented code point is distinct from the
-same character constructed from combining an accent and a letter;
-those are treated as two code points. For simplicity, this document
-will use the unqualified term character to refer to a Unicode code point
-in the source text.
-
-Each code point is distinct; for instance, upper and lower case letters
-are different characters.
-
-Implementation restriction: For compatibility with other tools, a
-compiler may disallow the NUL character (U+0000) in the source text.
-
-Implementation restriction: For compatibility with other tools, a
-compiler may ignore a UTF-8-encoded byte order mark
-(U+FEFF) if it is the first Unicode code point in the source text.
-A byte order mark may be disallowed anywhere else in the source.
-
-The following terms are used to denote specific Unicode character classes:
-
-In The Unicode Standard 8.0,
-Section 4.5 "General Category" defines a set of character categories.
-Go treats all characters in any of the Letter categories Lu, Ll, Lt, Lm, or Lo
-as Unicode letters, and those in the Number category Nd as Unicode digits.
-
-The underscore character
-Comments serve as program documentation. There are two forms:
-
-A comment cannot start inside a rune or
-string literal, or inside a comment.
-A general comment containing no newlines acts like a space.
-Any other comment acts like a newline.
-
-Tokens form the vocabulary of the Go language.
-There are four classes: identifiers, keywords, operators
-and punctuation, and literals. White space, formed from
-spaces (U+0020), horizontal tabs (U+0009),
-carriage returns (U+000D), and newlines (U+000A),
-is ignored except as it separates tokens
-that would otherwise combine into a single token. Also, a newline or end of file
-may trigger the insertion of a semicolon.
-While breaking the input into tokens,
-the next token is the longest sequence of characters that form a
-valid token.
-
-The formal grammar uses semicolons
-To reflect idiomatic use, code examples in this document elide semicolons
-using these rules.
-
-Identifiers name program entities such as variables and types.
-An identifier is a sequence of one or more letters and digits.
-The first character in an identifier must be a letter.
-
-Some identifiers are predeclared.
-
-The following keywords are reserved and may not be used as identifiers.
-
-The following character sequences represent operators
-(including assignment operators) and punctuation:
-
-An integer literal is a sequence of digits representing an
-integer constant.
-An optional prefix sets a non-decimal base:
-For readability, an underscore character
-A floating-point literal is a decimal or hexadecimal representation of a
-floating-point constant.
-
-A decimal floating-point literal consists of an integer part (decimal digits),
-a decimal point, a fractional part (decimal digits), and an exponent part
-(
-A hexadecimal floating-point literal consists of a
-For readability, an underscore character
-An imaginary literal represents the imaginary part of a
-complex constant.
-It consists of an integer or
-floating-point literal
-followed by the lower-case letter
-For backward compatibility, an imaginary literal's integer part consisting
-entirely of decimal digits (and possibly underscores) is considered a decimal
-integer, even if it starts with a leading
-A rune literal represents a rune constant,
-an integer value identifying a Unicode code point.
-A rune literal is expressed as one or more characters enclosed in single quotes,
-as in
-The simplest form represents the single character within the quotes;
-since Go source text is Unicode characters encoded in UTF-8, multiple
-UTF-8-encoded bytes may represent a single integer value. For
-instance, the literal
-Several backslash escapes allow arbitrary values to be encoded as
-ASCII text. There are four ways to represent the integer value
-as a numeric constant:
-Although these representations all result in an integer, they have
-different valid ranges. Octal escapes must represent a value between
-0 and 255 inclusive. Hexadecimal escapes satisfy this condition
-by construction. The escapes
-After a backslash, certain single-character escapes represent special values:
-
-All other sequences starting with a backslash are illegal inside rune literals.
-
-A string literal represents a string constant
-obtained from concatenating a sequence of characters. There are two forms:
-raw string literals and interpreted string literals.
-
-Raw string literals are character sequences between back quotes, as in
-
-Interpreted string literals are character sequences between double
-quotes, as in
-These examples all represent the same string:
-
-If the source code represents a character as two code points, such as
-a combining form involving an accent and a letter, the result will be
-an error if placed in a rune literal (it is not a single code
-point), and will appear as two code points if placed in a string
-literal.
- There are boolean constants,
-rune constants,
-integer constants,
-floating-point constants, complex constants,
-and string constants. Rune, integer, floating-point,
-and complex constants are
-collectively called numeric constants.
-
-A constant value is represented by a
-rune,
-integer,
-floating-point,
-imaginary,
-or
-string literal,
-an identifier denoting a constant,
-a constant expression,
-a conversion with a result that is a constant, or
-the result value of some built-in functions such as
-
-In general, complex constants are a form of
-constant expression
-and are discussed in that section.
-
-Numeric constants represent exact values of arbitrary precision and do not overflow.
-Consequently, there are no constants denoting the IEEE 754 negative zero, infinity,
-and not-a-number values.
-
-Constants may be typed or untyped.
-Literal constants,
-A constant may be given a type explicitly by a constant declaration
-or conversion, or implicitly when used in a
-variable declaration or an
-assignment or as an
-operand in an expression.
-It is an error if the constant value
-cannot be represented as a value of the respective type.
-
-An untyped constant has a default type which is the type to which the
-constant is implicitly converted in contexts where a typed value is required,
-for instance, in a short variable declaration
-such as
-Implementation restriction: Although numeric constants have arbitrary
-precision in the language, a compiler may implement them using an
-internal representation with limited precision. That said, every
-implementation must:
-
-These requirements apply both to literal constants and to the result
-of evaluating constant
-expressions.
-
-A variable is a storage location for holding a value.
-The set of permissible values is determined by the
-variable's type.
-
-A variable declaration
-or, for function parameters and results, the signature
-of a function declaration
-or function literal reserves
-storage for a named variable.
-
-Calling the built-in function
-Structured variables of array, slice,
-and struct types have elements and fields that may
-be addressed individually. Each such element
-acts like a variable.
-
-The static type (or just type) of a variable is the
-type given in its declaration, the type provided in the
-
-A variable's value is retrieved by referring to the variable in an
-expression; it is the most recent value
-assigned to the variable.
-If a variable has not yet been assigned a value, its value is the
-zero value for its type.
-
-A type determines a set of values together with operations and methods specific
-to those values. A type may be denoted by a type name, if it has one,
-or specified using a type literal, which composes a type from existing types.
-
-The language predeclares certain type names.
-Others are introduced with type declarations.
-Composite types—array, struct, pointer, function,
-interface, slice, map, and channel types—may be constructed using
-type literals.
-
-Each type
-The underlying type of
-A type has a (possibly empty) method set associated with it.
-The method set of an interface type is its interface.
-The method set of any other type
-The method set of a type determines the interfaces that the
-type implements
-and the methods that can be called
-using a receiver of that type.
-
-A boolean type represents the set of Boolean truth values
-denoted by the predeclared constants
-A numeric type represents sets of integer or floating-point values.
-The predeclared architecture-independent numeric types are:
-
-The value of an n-bit integer is n bits wide and represented using
-two's complement arithmetic.
-
-There is also a set of predeclared numeric types with implementation-specific sizes:
-
-To avoid portability issues all numeric types are defined
-types and thus distinct except
-
-A string type represents the set of string values.
-A string value is a (possibly empty) sequence of bytes.
-The number of bytes is called the length of the string and is never negative.
-Strings are immutable: once created,
-it is impossible to change the contents of a string.
-The predeclared string type is
-The length of a string
-An array is a numbered sequence of elements of a single
-type, called the element type.
-The number of elements is called the length of the array and is never negative.
-
-The length is part of the array's type; it must evaluate to a
-non-negative constant
-representable by a value
-of type
-A slice is a descriptor for a contiguous segment of an underlying array and
-provides access to a numbered sequence of elements from that array.
-A slice type denotes the set of all slices of arrays of its element type.
-The number of elements is called the length of the slice and is never negative.
-The value of an uninitialized slice is
-The length of a slice
-A slice, once initialized, is always associated with an underlying
-array that holds its elements. A slice therefore shares storage
-with its array and with other slices of the same array; by contrast,
-distinct arrays always represent distinct storage.
-
-The array underlying a slice may extend past the end of the slice.
-The capacity is a measure of that extent: it is the sum of
-the length of the slice and the length of the array beyond the slice;
-a slice of length up to that capacity can be created by
-slicing a new one from the original slice.
-The capacity of a slice
-A new, initialized slice value for a given element type
-produces the same slice as allocating an array and slicing
-it, so these two expressions are equivalent:
-
-Like arrays, slices are always one-dimensional but may be composed to construct
-higher-dimensional objects.
-With arrays of arrays, the inner arrays are, by construction, always the same length;
-however with slices of slices (or arrays of slices), the inner lengths may vary dynamically.
-Moreover, the inner slices must be initialized individually.
-
-A struct is a sequence of named elements, called fields, each of which has a
-name and a type. Field names may be specified explicitly (IdentifierList) or
-implicitly (EmbeddedField).
-Within a struct, non-blank field names must
-be unique.
-
-A field declared with a type but no explicit field name is called an embedded field.
-An embedded field must be specified as
-a type name
-The following declaration is illegal because field names must be unique
-in a struct type:
-
-A field or method
-Promoted fields act like ordinary fields
-of a struct except that they cannot be used as field names in
-composite literals of the struct.
-
-Given a struct type
-A field declaration may be followed by an optional string literal tag,
-which becomes an attribute for all the fields in the corresponding
-field declaration. An empty tag string is equivalent to an absent tag.
-The tags are made visible through a reflection interface
-and take part in type identity for structs
-but are otherwise ignored.
-
-A pointer type denotes the set of all pointers to variables of a given
-type, called the base type of the pointer.
-The value of an uninitialized pointer is
-A function type denotes the set of all functions with the same parameter
-and result types. The value of an uninitialized variable of function type
-is
-Within a list of parameters or results, the names (IdentifierList)
-must either all be present or all be absent. If present, each name
-stands for one item (parameter or result) of the specified type and
-all non-blank names in the signature
-must be unique.
-If absent, each type stands for one item of that type.
-Parameter and result
-lists are always parenthesized except that if there is exactly
-one unnamed result it may be written as an unparenthesized type.
-
-The final incoming parameter in a function signature may have
-a type prefixed with
-An interface type specifies a method set called its interface.
-A variable of interface type can store a value of any type with a method set
-that is any superset of the interface. Such a type is said to
-implement the interface.
-The value of an uninitialized variable of interface type is
-An interface type may specify methods explicitly through method specifications,
-or it may embed methods of other interfaces through interface type names.
-
-The name of each explicitly specified method must be unique
-and not blank.
-
-More than one type may implement an interface.
-For instance, if two types
-(where
-A type implements any interface comprising any subset of its methods
-and may therefore implement several distinct interfaces. For
-instance, all types implement the empty interface:
-
-Similarly, consider this interface specification,
-which appears within a type declaration
-to define an interface called
-If
-they implement the
-An interface
-A union of method sets contains the (exported and non-exported)
-methods of each method set exactly once, and methods with the
-same names must
-have identical signatures.
-
-An interface type
-A map is an unordered group of elements of one type, called the
-element type, indexed by a set of unique keys of another type,
-called the key type.
-The value of an uninitialized map is
-The comparison operators
-
-The number of map elements is called its length.
-For a map
-A new, empty map value is made using the built-in
-function
-The initial capacity does not bound its size:
-maps grow to accommodate the number of items
-stored in them, with the exception of
-A channel provides a mechanism for
-concurrently executing functions
-to communicate by
-sending and
-receiving
-values of a specified element type.
-The value of an uninitialized channel is
-The optional
-The
-A new, initialized channel
-value can be made using the built-in function
-
-The capacity, in number of elements, sets the size of the buffer in the channel.
-If the capacity is zero or absent, the channel is unbuffered and communication
-succeeds only when both a sender and receiver are ready. Otherwise, the channel
-is buffered and communication succeeds without blocking if the buffer
-is not full (sends) or not empty (receives).
-A
-A channel may be closed with the built-in function
-
-A single channel may be used in
-send statements,
-receive operations,
-and calls to the built-in functions
-
-Two types are either identical or different.
-
-A defined type is always different from any other type.
-Otherwise, two types are identical if their underlying type literals are
-structurally equivalent; that is, they have the same literal structure and corresponding
-components have identical types. In detail:
-
-Given the declarations
-
-these types are identical:
-
-
-A value
-A constant
-A block is a possibly empty sequence of declarations and statements
-within matching brace brackets.
-
-In addition to explicit blocks in the source code, there are implicit blocks:
-
-Blocks nest and influence scoping.
-
-A declaration binds a non-blank identifier to a
-constant,
-type,
-variable,
-function,
-label, or
-package.
-Every identifier in a program must be declared.
-No identifier may be declared twice in the same block, and
-no identifier may be declared in both the file and package block.
-
-The blank identifier may be used like any other identifier
-in a declaration, but it does not introduce a binding and thus is not declared.
-In the package block, the identifier
-The scope of a declared identifier is the extent of source text in which
-the identifier denotes the specified constant, type, variable, function, label, or package.
-
-Go is lexically scoped using blocks:
-
-An identifier declared in a block may be redeclared in an inner block.
-While the identifier of the inner declaration is in scope, it denotes
-the entity declared by the inner declaration.
-
-The package clause is not a declaration; the package name
-does not appear in any scope. Its purpose is to identify the files belonging
-to the same package and to specify the default package name for import
-declarations.
-
-Labels are declared by labeled statements and are
-used in the "break",
-"continue", and
-"goto" statements.
-It is illegal to define a label that is never used.
-In contrast to other identifiers, labels are not block scoped and do
-not conflict with identifiers that are not labels. The scope of a label
-is the body of the function in which it is declared and excludes
-the body of any nested function.
-
-The blank identifier is represented by the underscore character
-The following identifiers are implicitly declared in the
-universe block:
-
-An identifier may be exported to permit access to it from another package.
-An identifier is exported if both:
-
-All other identifiers are not exported.
-
-Given a set of identifiers, an identifier is called unique if it is
-different from every other in the set.
-Two identifiers are different if they are spelled differently, or if they
-appear in different packages and are not
-exported. Otherwise, they are the same.
-
-A constant declaration binds a list of identifiers (the names of
-the constants) to the values of a list of constant expressions.
-The number of identifiers must be equal
-to the number of expressions, and the nth identifier on
-the left is bound to the value of the nth expression on the
-right.
-
-If the type is present, all constants take the type specified, and
-the expressions must be assignable to that type.
-If the type is omitted, the constants take the
-individual types of the corresponding expressions.
-If the expression values are untyped constants,
-the declared constants remain untyped and the constant identifiers
-denote the constant values. For instance, if the expression is a
-floating-point literal, the constant identifier denotes a floating-point
-constant, even if the literal's fractional part is zero.
-
-Within a parenthesized
-Within a constant declaration, the predeclared identifier
-
-By definition, multiple uses of
-This last example exploits the implicit repetition
-of the last non-empty expression list.
-
-A type declaration binds an identifier, the type name, to a type.
-Type declarations come in two forms: alias declarations and type definitions.
-
-An alias declaration binds an identifier to the given type.
-
-Within the scope of
-the identifier, it serves as an alias for the type.
-
-A type definition creates a new, distinct type with the same
-underlying type and operations as the given type,
-and binds an identifier to it.
-
-The new type is called a defined type.
-It is different from any other type,
-including the type it is created from.
-
-A defined type may have methods associated with it.
-It does not inherit any methods bound to the given type,
-but the method set
-of an interface type or of elements of a composite type remains unchanged:
-
-Type definitions may be used to define different boolean, numeric,
-or string types and associate methods with them:
-
-A variable declaration creates one or more variables,
-binds corresponding identifiers to them, and gives each a type and an initial value.
-
-If a list of expressions is given, the variables are initialized
-with the expressions following the rules for assignments.
-Otherwise, each variable is initialized to its zero value.
-
-If a type is present, each variable is given that type.
-Otherwise, each variable is given the type of the corresponding
-initialization value in the assignment.
-If that value is an untyped constant, it is first implicitly
-converted to its default type;
-if it is an untyped boolean value, it is first implicitly converted to type
-Implementation restriction: A compiler may make it illegal to declare a variable
-inside a function body if the variable is
-never used.
-
-A short variable declaration uses the syntax:
-
-It is shorthand for a regular variable declaration
-with initializer expressions but no types:
-
-Unlike regular variable declarations, a short variable declaration may redeclare
-variables provided they were originally declared earlier in the same block
-(or the parameter lists if the block is the function body) with the same type,
-and at least one of the non-blank variables is new.
-As a consequence, redeclaration can only appear in a multi-variable short declaration.
-Redeclaration does not introduce a new variable; it just assigns a new value to the original.
-
-Short variable declarations may appear only inside functions.
-In some contexts such as the initializers for
-"if",
-"for", or
-"switch" statements,
-they can be used to declare local temporary variables.
-
-A function declaration binds an identifier, the function name,
-to a function.
-
-If the function's signature declares
-result parameters, the function body's statement list must end in
-a terminating statement.
-
-A function declaration may omit the body. Such a declaration provides the
-signature for a function implemented outside Go, such as an assembly routine.
-
-A method is a function with a receiver.
-A method declaration binds an identifier, the method name, to a method,
-and associates the method with the receiver's base type.
-
-The receiver is specified via an extra parameter section preceding the method
-name. That parameter section must declare a single non-variadic parameter, the receiver.
-Its type must be a defined type
-A non-blank receiver identifier must be
-unique in the method signature.
-If the receiver's value is not referenced inside the body of the method,
-its identifier may be omitted in the declaration. The same applies in
-general to parameters of functions and methods.
-
-For a base type, the non-blank names of methods bound to it must be unique.
-If the base type is a struct type,
-the non-blank method and field names must be distinct.
-
-Given defined type
-bind the methods
-The type of a method is the type of a function with the receiver as first
-argument. For instance, the method
-However, a function declared this way is not a method.
-
-An expression specifies the computation of a value by applying
-operators and functions to operands.
-
-Operands denote the elementary values in an expression. An operand may be a
-literal, a (possibly qualified)
-non-blank identifier denoting a
-constant,
-variable, or
-function,
-or a parenthesized expression.
-
-The blank identifier may appear as an
-operand only on the left-hand side of an assignment.
-
-A qualified identifier is an identifier qualified with a package name prefix.
-Both the package name and the identifier must not be
-blank.
-
-A qualified identifier accesses an identifier in a different package, which
-must be imported.
-The identifier must be exported and
-declared in the package block of that package.
-
-Composite literals construct values for structs, arrays, slices, and maps
-and create a new value each time they are evaluated.
-They consist of the type of the literal followed by a brace-bound list of elements.
-Each element may optionally be preceded by a corresponding key.
-
-The LiteralType's underlying type must be a struct, array, slice, or map type
-(the grammar enforces this constraint except when the type is given
-as a TypeName).
-The types of the elements and keys must be assignable
-to the respective field, element, and key types of the literal type;
-there is no additional conversion.
-The key is interpreted as a field name for struct literals,
-an index for array and slice literals, and a key for map literals.
-For map literals, all elements must have a key. It is an error
-to specify multiple elements with the same field name or
-constant key value. For non-constant map keys, see the section on
-evaluation order.
-
-For struct literals the following rules apply:
-
-Given the declarations
-
-one may write
-
-For array and slice literals the following rules apply:
-
-Taking the address of a composite literal
-generates a pointer to a unique variable initialized
-with the literal's value.
-
-Note that the zero value for a slice or map
-type is not the same as an initialized but empty value of the same type.
-Consequently, taking the address of an empty slice or map composite literal
-does not have the same effect as allocating a new slice or map value with
-new.
-
-The length of an array literal is the length specified in the literal type.
-If fewer elements than the length are provided in the literal, the missing
-elements are set to the zero value for the array element type.
-It is an error to provide elements with index values outside the index range
-of the array. The notation
-A slice literal describes the entire underlying array literal.
-Thus the length and capacity of a slice literal are the maximum
-element index plus one. A slice literal has the form
-
-and is shorthand for a slice operation applied to an array:
-
-Within a composite literal of array, slice, or map type
-A parsing ambiguity arises when a composite literal using the
-TypeName form of the LiteralType appears as an operand between the
-keyword and the opening brace of the block
-of an "if", "for", or "switch" statement, and the composite literal
-is not enclosed in parentheses, square brackets, or curly braces.
-In this rare case, the opening brace of the literal is erroneously parsed
-as the one introducing the block of statements. To resolve the ambiguity,
-the composite literal must appear within parentheses.
-
-Examples of valid array, slice, and map literals:
-
-A function literal represents an anonymous function.
-
-A function literal can be assigned to a variable or invoked directly.
-
-Function literals are closures: they may refer to variables
-defined in a surrounding function. Those variables are then shared between
-the surrounding function and the function literal, and they survive as long
-as they are accessible.
-
-Primary expressions are the operands for unary and binary expressions.
-
-For a primary expression
-denotes the field or method
-A selector
-The following rules apply to selectors:
-
-For example, given the declarations:
-
-one may write:
-
-but the following is invalid:
-
-If
-Consider a struct type
-The expression
-
-yields a function equivalent to
-That function may be called normally with an explicit receiver, so
-these five invocations are equivalent:
-
-Similarly, the expression
-
-yields a function value representing
-For a method with a value receiver, one can derive a function
-with an explicit pointer receiver, so
-
-yields a function value representing
-Such a function indirects through the receiver to create a value
-to pass as the receiver to the underlying method;
-the method does not overwrite the value whose address is passed in
-the function call.
-
-The final case, a value-receiver function for a pointer-receiver method,
-is illegal because pointer-receiver methods are not in the method set
-of the value type.
-
-Function values derived from methods are called with function call syntax;
-the receiver is provided as the first argument to the call.
-That is, given
-It is legal to derive a function value from a method of an interface type.
-The resulting function takes an explicit receiver of that interface type.
-
-If the expression
-The type
-As in the discussion of method expressions above,
-consider a struct type
-The expression
-
-yields a function value of type
-
-These two invocations are equivalent:
-
-Similarly, the expression
-
-yields a function value of type
-
-As with selectors, a reference to a non-interface method with a value receiver
-using a pointer will automatically dereference that pointer:
-As with method calls, a reference to a non-interface method with a pointer receiver
-using an addressable value will automatically take the address of that value:
-Although the examples above use non-interface types, it is also legal to create a method value
-from a value of interface type.
-
-A primary expression of the form
-
-denotes the element of the array, pointer to array, slice, string or map
-If
-For
-For
-For
-For
-For
-Otherwise
-An index expression on a map
-yields an additional untyped boolean value. The value of
-Assigning to an element of a
-Slice expressions construct a substring or slice from a string, array, pointer
-to array, or slice. There are two variants: a simple form that specifies a low
-and high bound, and a full form that also specifies a bound on the capacity.
-
-For a string, array, pointer to array, or slice
-constructs a substring or slice. The indices
-the slice
-For convenience, any of the indices may be omitted. A missing
-If
-For arrays or strings, the indices are in range if
-
-Except for untyped strings, if the sliced operand is a string or slice,
-the result of the slice operation is a non-constant value of the same type as the operand.
-For untyped string operands the result is a non-constant value of type
-If the sliced operand of a valid slice expression is a
-For an array, pointer to array, or slice
-constructs a slice of the same type, and with the same length and elements as the simple slice
-expression
-the slice
-As for simple slice expressions, if
-The indices are in range if
-For an expression
-asserts that
-More precisely, if
-If the type assertion holds, the value of the expression is the value
-stored in
-A type assertion used in an assignment or initialization of the special form
-
-yields an additional untyped boolean value. The value of
-Given an expression
-calls
-In a function call, the function value and arguments are evaluated in
-the usual order.
-After they are evaluated, the parameters of the call are passed by value to the function
-and the called function begins execution.
-The return parameters of the function are passed by value
-back to the caller when the function returns.
-
-Calling a
-As a special case, if the return values of a function or method
-
-A method call
-There is no distinct method type and there are no method literals.
-
-If
-Given the function and calls
-
-within
-If the final argument is assignable to a slice type
-Given the slice
-within
-Operators combine operands into expressions.
-
-Comparisons are discussed elsewhere.
-For other binary operators, the operand types must be identical
-unless the operation involves shifts or untyped constants.
-For operations involving constants only, see the section on
-constant expressions.
-
-Except for shift operations, if one operand is an untyped constant
-and the other operand is not, the constant is implicitly converted
-to the type of the other operand.
-
-The right operand in a shift expression must have integer type
-or be an untyped constant representable by a
-value of type
-Unary operators have the highest precedence.
-As the
-There are five precedence levels for binary operators.
-Multiplication operators bind strongest, followed by addition
-operators, comparison operators,
-Binary operators of the same precedence associate from left to right.
-For instance,
-Arithmetic operators apply to numeric values and yield a result of the same
-type as the first operand. The four standard arithmetic operators (
-For two integer values
-with
-The one exception to this rule is that if the dividend
-If the divisor is a constant, it must not be zero.
-If the divisor is zero at run time, a run-time panic occurs.
-If the dividend is non-negative and the divisor is a constant power of 2,
-the division may be replaced by a right shift, and computing the remainder may
-be replaced by a bitwise AND operation:
-
-The shift operators shift the left operand by the shift count specified by the
-right operand, which must be non-negative. If the shift count is negative at run time,
-a run-time panic occurs.
-The shift operators implement arithmetic shifts if the left operand is a signed
-integer and logical shifts if it is an unsigned integer.
-There is no upper limit on the shift count. Shifts behave
-as if the left operand is shifted
-For integer operands, the unary operators
-
-For unsigned integer values, the operations
-For signed integers, the operations
-For floating-point and complex numbers,
-
-An implementation may combine multiple floating-point operations into a single
-fused operation, possibly across statements, and produce a result that differs
-from the value obtained by executing and rounding the instructions individually.
-An explicit floating-point type conversion rounds to
-the precision of the target type, preventing fusion that would discard that rounding.
-
-For instance, some architectures provide a "fused multiply and add" (FMA) instruction
-that computes
-Strings can be concatenated using the
-String addition creates a new string by concatenating the operands.
-
-Comparison operators compare two operands and yield an untyped boolean value.
-
-In any comparison, the first operand
-must be assignable
-to the type of the second operand, or vice versa.
-
-The equality operators
-A comparison of two interface values with identical dynamic types
-causes a run-time panic if values
-of that type are not comparable. This behavior applies not only to direct interface
-value comparisons but also when comparing arrays of interface values
-or structs with interface-valued fields.
-
-Slice, map, and function values are not comparable.
-However, as a special case, a slice, map, or function value may
-be compared to the predeclared identifier
-Logical operators apply to boolean values
-and yield a result of the same type as the operands.
-The right operand is evaluated conditionally.
-
-For an operand
-For an operand
-For an operand
-A receive expression used in an assignment or initialization of the special form
-
-yields an additional untyped boolean result reporting whether the
-communication succeeded. The value of
-A conversion changes the type of an expression
-to the type specified by the conversion.
-A conversion may appear literally in the source, or it may be implied
-by the context in which an expression appears.
-
-An explicit conversion is an expression of the form
-If the type starts with the operator
-A constant value
-Converting a constant yields a typed constant as result.
-
-A non-constant value
-Struct tags are ignored when comparing struct types
-for identity for the purpose of conversion:
-
-Specific rules apply to (non-constant) conversions between numeric types or
-to and from a string type.
-These conversions may change the representation of
-There is no linguistic mechanism to convert between pointers and integers.
-The package
-For the conversion of non-constant numeric values, the following rules apply:
-
-In all non-constant conversions involving floating-point or complex values,
-if the result type cannot represent the value the conversion
-succeeds but the result value is implementation-dependent.
-
-Converting a slice to an array pointer yields a pointer to the underlying array of the slice.
-If the length of the slice is less than the length of the array,
-a run-time panic occurs.
-
-Constant expressions may contain only constant
-operands and are evaluated at compile time.
-
-Untyped boolean, numeric, and string constants may be used as operands
-wherever it is legal to use an operand of boolean, numeric, or string type,
-respectively.
-
-A constant comparison always yields
-an untyped boolean constant. If the left operand of a constant
-shift expression is an untyped constant, the
-result is an integer constant; otherwise it is a constant of the same
-type as the left operand, which must be of
-integer type.
-
-Any other operation on untyped constants results in an untyped constant of the
-same kind; that is, a boolean, integer, floating-point, complex, or string
-constant.
-If the untyped operands of a binary operation (other than a shift) are of
-different kinds, the result is of the operand's kind that appears later in this
-list: integer, rune, floating-point, complex.
-For example, an untyped integer constant divided by an
-untyped complex constant yields an untyped complex constant.
-
-Applying the built-in function
-Constant expressions are always evaluated exactly; intermediate values and the
-constants themselves may require precision significantly larger than supported
-by any predeclared type in the language. The following are legal declarations:
-
-The divisor of a constant division or remainder operation must not be zero:
-
-The values of typed constants must always be accurately
-representable by values
-of the constant type. The following constant expressions are illegal:
-
-The mask used by the unary bitwise complement operator
-Implementation restriction: A compiler may use rounding while
-computing untyped floating-point or complex constant expressions; see
-the implementation restriction in the section
-on constants. This rounding may cause a
-floating-point constant expression to be invalid in an integer
-context, even if it would be integral when calculated using infinite
-precision, and vice versa.
-
-At package level, initialization dependencies
-determine the evaluation order of individual initialization expressions in
-variable declarations.
-Otherwise, when evaluating the operands of an
-expression, assignment, or
-return statement,
-all function calls, method calls, and
-communication operations are evaluated in lexical left-to-right
-order.
-
-For example, in the (function-local) assignment
-
-the function calls and communication happen in the order
-
-At package level, initialization dependencies override the left-to-right rule
-for individual initialization expressions, but not for operands within each
-expression:
-
-The function calls happen in the order
-
-Floating-point operations within a single expression are evaluated according to
-the associativity of the operators. Explicit parentheses affect the evaluation
-by overriding the default associativity.
-In the expression
-Statements control execution.
-
-A terminating statement interrupts the regular flow of control in
-a block. The following statements are terminating:
-
-All other statements are not terminating.
-
-A statement list ends in a terminating statement if the list
-is not empty and its final non-empty statement is terminating.
-
-The empty statement does nothing.
-
-A labeled statement may be the target of a
-With the exception of specific built-in functions,
-function and method calls and
-receive operations
-can appear in statement context. Such statements may be parenthesized.
-
-The following built-in functions are not permitted in statement context:
-
-A send statement sends a value on a channel.
-The channel expression must be of channel type,
-the channel direction must permit send operations,
-and the type of the value to be sent must be assignable
-to the channel's element type.
-
-Both the channel and the value expression are evaluated before communication
-begins. Communication blocks until the send can proceed.
-A send on an unbuffered channel can proceed if a receiver is ready.
-A send on a buffered channel can proceed if there is room in the buffer.
-A send on a closed channel proceeds by causing a run-time panic.
-A send on a
-The "++" and "--" statements increment or decrement their operands
-by the untyped constant
-The following assignment statements are semantically
-equivalent:
-
-Each left-hand side operand must be addressable,
-a map index expression, or (for
-An assignment operation
-A tuple assignment assigns the individual elements of a multi-valued
-operation to a list of variables. There are two forms. In the
-first, the right hand operand is a single multi-valued expression
-such as a function call, a channel or
-map operation, or a type assertion.
-The number of operands on the left
-hand side must match the number of values. For instance, if
-
-assigns the first value to
-The blank identifier provides a way to
-ignore right-hand side values in an assignment:
-
-The assignment proceeds in two phases.
-First, the operands of index expressions
-and pointer indirections
-(including implicit pointer indirections in selectors)
-on the left and the expressions on the right are all
-evaluated in the usual order.
-Second, the assignments are carried out in left-to-right order.
-
-In assignments, each value must be assignable
-to the type of the operand to which it is assigned, with the following special cases:
-
-"If" statements specify the conditional execution of two branches
-according to the value of a boolean expression. If the expression
-evaluates to true, the "if" branch is executed, otherwise, if
-present, the "else" branch is executed.
-
-The expression may be preceded by a simple statement, which
-executes before the expression is evaluated.
-
-"Switch" statements provide multi-way execution.
-An expression or type is compared to the "cases"
-inside the "switch" to determine which branch
-to execute.
-
-There are two forms: expression switches and type switches.
-In an expression switch, the cases contain expressions that are compared
-against the value of the switch expression.
-In a type switch, the cases contain types that are compared against the
-type of a specially annotated switch expression.
-The switch expression is evaluated exactly once in a switch statement.
-
-In an expression switch,
-the switch expression is evaluated and
-the case expressions, which need not be constants,
-are evaluated left-to-right and top-to-bottom; the first one that equals the
-switch expression
-triggers execution of the statements of the associated case;
-the other cases are skipped.
-If no case matches and there is a "default" case,
-its statements are executed.
-There can be at most one default case and it may appear anywhere in the
-"switch" statement.
-A missing switch expression is equivalent to the boolean value
-
-If the switch expression evaluates to an untyped constant, it is first implicitly
-converted to its default type.
-The predeclared untyped value
-If a case expression is untyped, it is first implicitly converted
-to the type of the switch expression.
-For each (possibly converted) case expression
-In other words, the switch expression is treated as if it were used to declare and
-initialize a temporary variable
-In a case or default clause, the last non-empty statement
-may be a (possibly labeled)
-"fallthrough" statement to
-indicate that control should flow from the end of this clause to
-the first statement of the next clause.
-Otherwise control flows to the end of the "switch" statement.
-A "fallthrough" statement may appear as the last statement of all
-but the last clause of an expression switch.
-
-The switch expression may be preceded by a simple statement, which
-executes before the expression is evaluated.
-
-Implementation restriction: A compiler may disallow multiple case
-expressions evaluating to the same constant.
-For instance, the current compilers disallow duplicate integer,
-floating point, or string constants in case expressions.
-
-A type switch compares types rather than values. It is otherwise similar
-to an expression switch. It is marked by a special switch expression that
-has the form of a type assertion
-using the keyword
-Cases then match actual types
-The TypeSwitchGuard may include a
-short variable declaration.
-When that form is used, the variable is declared at the end of the
-TypeSwitchCase in the implicit block of each clause.
-In clauses with a case listing exactly one type, the variable
-has that type; otherwise, the variable has the type of the expression
-in the TypeSwitchGuard.
-
-Instead of a type, a case may use the predeclared identifier
-
-Given an expression
-could be rewritten:
-
-The type switch guard may be preceded by a simple statement, which
-executes before the guard is evaluated.
-
-The "fallthrough" statement is not permitted in a type switch.
-
-A "for" statement specifies repeated execution of a block. There are three forms:
-The iteration may be controlled by a single condition, a "for" clause, or a "range" clause.
-
-In its simplest form, a "for" statement specifies the repeated execution of
-a block as long as a boolean condition evaluates to true.
-The condition is evaluated before each iteration.
-If the condition is absent, it is equivalent to the boolean value
-
-A "for" statement with a ForClause is also controlled by its condition, but
-additionally it may specify an init
-and a post statement, such as an assignment,
-an increment or decrement statement. The init statement may be a
-short variable declaration, but the post statement must not.
-Variables declared by the init statement are re-used in each iteration.
-
-If non-empty, the init statement is executed once before evaluating the
-condition for the first iteration;
-the post statement is executed after each execution of the block (and
-only if the block was executed).
-Any element of the ForClause may be empty but the
-semicolons are
-required unless there is only a condition.
-If the condition is absent, it is equivalent to the boolean value
-
-A "for" statement with a "range" clause
-iterates through all entries of an array, slice, string or map,
-or values received on a channel. For each entry it assigns iteration values
-to corresponding iteration variables if present and then executes the block.
-
-The expression on the right in the "range" clause is called the range expression,
-which may be an array, pointer to an array, slice, string, map, or channel permitting
-receive operations.
-As with an assignment, if present the operands on the left must be
-addressable or map index expressions; they
-denote the iteration variables. If the range expression is a channel, at most
-one iteration variable is permitted, otherwise there may be up to two.
-If the last iteration variable is the blank identifier,
-the range clause is equivalent to the same clause without that identifier.
-
-The range expression
-Function calls on the left are evaluated once per iteration.
-For each iteration, iteration values are produced as follows
-if the respective iteration variables are present:
-
-The iteration values are assigned to the respective
-iteration variables as in an assignment statement.
-
-The iteration variables may be declared by the "range" clause using a form of
-short variable declaration
-(
-A "go" statement starts the execution of a function call
-as an independent concurrent thread of control, or goroutine,
-within the same address space.
-
-The expression must be a function or method call; it cannot be parenthesized.
-Calls of built-in functions are restricted as for
-expression statements.
-
-The function value and parameters are
-evaluated as usual
-in the calling goroutine, but
-unlike with a regular call, program execution does not wait
-for the invoked function to complete.
-Instead, the function begins executing independently
-in a new goroutine.
-When the function terminates, its goroutine also terminates.
-If the function has any return values, they are discarded when the
-function completes.
-
-A "select" statement chooses which of a set of possible
-send or
-receive
-operations will proceed.
-It looks similar to a
-"switch" statement but with the
-cases all referring to communication operations.
-
-A case with a RecvStmt may assign the result of a RecvExpr to one or
-two variables, which may be declared using a
-short variable declaration.
-The RecvExpr must be a (possibly parenthesized) receive operation.
-There can be at most one default case and it may appear anywhere
-in the list of cases.
-
-Execution of a "select" statement proceeds in several steps:
-
-Since communication on
-A "return" statement in a function
-In a function without a result type, a "return" statement must not
-specify any result values.
-
-There are three ways to return values from a function with a result
-type:
-
-Regardless of how they are declared, all the result values are initialized to
-the zero values for their type upon entry to the
-function. A "return" statement that specifies results sets the result parameters before
-any deferred functions are executed.
-
-Implementation restriction: A compiler may disallow an empty expression list
-in a "return" statement if a different entity (constant, type, or variable)
-with the same name as a result parameter is in
-scope at the place of the return.
-
-A "break" statement terminates execution of the innermost
-"for",
-"switch", or
-"select" statement
-within the same function.
-
-If there is a label, it must be that of an enclosing
-"for", "switch", or "select" statement,
-and that is the one whose execution terminates.
-
-A "continue" statement begins the next iteration of the
-innermost "for" loop at its post statement.
-The "for" loop must be within the same function.
-
-If there is a label, it must be that of an enclosing
-"for" statement, and that is the one whose execution
-advances.
-
-A "goto" statement transfers control to the statement with the corresponding label
-within the same function.
-
-Executing the "goto" statement must not cause any variables to come into
-scope that were not already in scope at the point of the goto.
-For instance, this example:
-
-is erroneous because the jump to label
-A "goto" statement outside a block cannot jump to a label inside that block.
-For instance, this example:
-
-is erroneous because the label
-A "fallthrough" statement transfers control to the first statement of the
-next case clause in an expression "switch" statement.
-It may be used only as the final non-empty statement in such a clause.
-
-A "defer" statement invokes a function whose execution is deferred
-to the moment the surrounding function returns, either because the
-surrounding function executed a return statement,
-reached the end of its function body,
-or because the corresponding goroutine is panicking.
-
-The expression must be a function or method call; it cannot be parenthesized.
-Calls of built-in functions are restricted as for
-expression statements.
-
-Each time a "defer" statement
-executes, the function value and parameters to the call are
-evaluated as usual
-and saved anew but the actual function is not invoked.
-Instead, deferred functions are invoked immediately before
-the surrounding function returns, in the reverse order
-they were deferred. That is, if the surrounding function
-returns through an explicit return statement,
-deferred functions are executed after any result parameters are set
-by that return statement but before the function returns to its caller.
-If a deferred function value evaluates
-to
-For instance, if the deferred function is
-a function literal and the surrounding
-function has named result parameters that
-are in scope within the literal, the deferred function may access and modify
-the result parameters before they are returned.
-If the deferred function has any return values, they are discarded when
-the function completes.
-(See also the section on handling panics.)
-
-Built-in functions are
-predeclared.
-They are called like any other function but some of them
-accept a type instead of an expression as the first argument.
-
-The built-in functions do not have standard Go types,
-so they can only appear in call expressions;
-they cannot be used as function values.
-
-For a channel
-The built-in functions
-The capacity of a slice is the number of elements for which there is
-space allocated in the underlying array.
-At any time the following relationship holds:
-
-The length of a
-The expression
-The built-in function
-For instance
-
-allocates storage for a variable of type
-The built-in function
-Each of the size arguments
-Calling
-The built-in functions
-The variadic function
-If the capacity of
-The function
-Examples:
-
-The built-in function
-If the map
-Three functions assemble and disassemble complex numbers.
-The built-in function
-The type of the arguments and return value correspond.
-For
-For
-The
-If the operands of these functions are all constants, the return
-value is a constant.
- Two built-in functions,
-While executing a function
-The
-The return value of
-The
-Current implementations provide several built-in functions useful during
-bootstrapping. These functions are documented for completeness but are not
-guaranteed to stay in the language. They do not return a result.
-
-Implementation restriction:
-Go programs are constructed by linking together packages.
-A package in turn is constructed from one or more source files
-that together declare constants, types, variables and functions
-belonging to the package and which are accessible in all files
-of the same package. Those elements may be
-exported and used in another package.
-
-Each source file consists of a package clause defining the package
-to which it belongs, followed by a possibly empty set of import
-declarations that declare packages whose contents it wishes to use,
-followed by a possibly empty set of declarations of functions,
-types, variables, and constants.
-
-A package clause begins each source file and defines the package
-to which the file belongs.
-
-The PackageName must not be the blank identifier.
-
-A set of files sharing the same PackageName form the implementation of a package.
-An implementation may require that all source files for a package inhabit the same directory.
-
-An import declaration states that the source file containing the declaration
-depends on functionality of the imported package
-(§Program initialization and execution)
-and enables access to exported identifiers
-of that package.
-The import names an identifier (PackageName) to be used for access and an ImportPath
-that specifies the package to be imported.
-
-The PackageName is used in qualified identifiers
-to access exported identifiers of the package within the importing source file.
-It is declared in the file block.
-If the PackageName is omitted, it defaults to the identifier specified in the
-package clause of the imported package.
-If an explicit period (
-The interpretation of the ImportPath is implementation-dependent but
-it is typically a substring of the full file name of the compiled
-package and may be relative to a repository of installed packages.
-
-Implementation restriction: A compiler may restrict ImportPaths to
-non-empty strings using only characters belonging to
-Unicode's
-L, M, N, P, and S general categories (the Graphic characters without
-spaces) and may also exclude the characters
-
-Assume we have compiled a package containing the package clause
-
-An import declaration declares a dependency relation between
-the importing and imported package.
-It is illegal for a package to import itself, directly or indirectly,
-or to directly import a package without
-referring to any of its exported identifiers. To import a package solely for
-its side-effects (initialization), use the blank
-identifier as explicit package name:
-
-Here is a complete Go package that implements a concurrent prime sieve.
-
-When storage is allocated for a variable,
-either through a declaration or a call of
-These two simple declarations are equivalent:
-
-After
-
-the following holds:
-
-The same would also be true after
-
-Within a package, package-level variable initialization proceeds stepwise,
-with each step selecting the variable earliest in declaration order
-which has no dependencies on uninitialized variables.
-
-More precisely, a package-level variable is considered ready for
-initialization if it is not yet initialized and either has
-no initialization expression or
-its initialization expression has no dependencies on uninitialized variables.
-Initialization proceeds by repeatedly initializing the next package-level
-variable that is earliest in declaration order and ready for initialization,
-until there are no variables ready for initialization.
-
-If any variables are still uninitialized when this
-process ends, those variables are part of one or more initialization cycles,
-and the program is not valid.
-
-Multiple variables on the left-hand side of a variable declaration initialized
-by single (multi-valued) expression on the right-hand side are initialized
-together: If any of the variables on the left-hand side is initialized, all
-those variables are initialized in the same step.
-
-For the purpose of package initialization, blank
-variables are treated like any other variables in declarations.
-
-The declaration order of variables declared in multiple files is determined
-by the order in which the files are presented to the compiler: Variables
-declared in the first file are declared before any of the variables declared
-in the second file, and so on.
-
-Dependency analysis does not rely on the actual values of the
-variables, only on lexical references to them in the source,
-analyzed transitively. For instance, if a variable
-For example, given the declarations
-
-the initialization order is
-Dependency analysis is performed per package; only references referring
-to variables, functions, and (non-interface) methods declared in the current
-package are considered. If other, hidden, data dependencies exists between
-variables, the initialization order between those variables is unspecified.
-
-For instance, given the declarations
-
-the variable
-Variables may also be initialized using functions named
-Multiple such functions may be defined per package, even within a single
-source file. In the package block, the
-A package with no imports is initialized by assigning initial values
-to all its package-level variables followed by calling all
-Package initialization—variable initialization and the invocation of
-
-To ensure reproducible initialization behavior, build systems are encouraged
-to present multiple files belonging to the same package in lexical file name
-order to a compiler.
-
-A complete program is created by linking a single, unimported package
-called the main package with all the packages it imports, transitively.
-The main package must
-have package name
-Program execution begins by initializing the main package and then
-invoking the function
-The predeclared type
-It is the conventional interface for representing an error condition,
-with the nil value representing no error.
-For instance, a function to read data from a file might be defined:
-
-Execution errors such as attempting to index an array out
-of bounds trigger a run-time panic equivalent to a call of
-the built-in function
-The built-in package
-A
-The functions
-The function
-Computer architectures may require memory addresses to be aligned;
-that is, for addresses of a variable to be a multiple of a factor,
-the variable's type's alignment. The function
-Calls to
-The function
-The function
-except that, as a special case, if
-The
-For the numeric types, the following sizes are guaranteed:
-
-The following minimal alignment properties are guaranteed:
-
-A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.
-Introduction
-
-Notation
-
-Production = production_name "=" [ Expression ] "." .
-Expression = Alternative { "|" Alternative } .
-Alternative = Term { Term } .
-Term = production_name | token [ "…" token ] | Group | Option | Repetition .
-Group = "(" Expression ")" .
-Option = "[" Expression "]" .
-Repetition = "{" Expression "}" .
-
-
-
-| alternation
-() grouping
-[] option (0 or 1 times)
-{} repetition (0 to n times)
-
-
-"" or back quotes ``.
-a … b represents the set of characters from
-a through b as alternatives. The horizontal
-ellipsis … is also used elsewhere in the spec to informally denote various
-enumerations or code snippets that are not further specified. The character …
-(as opposed to the three characters ...) is not a token of the Go
-language.
-Source code representation
-
-Characters
-
-
-newline = /* the Unicode code point U+000A */ .
-unicode_char = /* an arbitrary Unicode code point except newline */ .
-unicode_letter = /* a Unicode code point classified as "Letter" */ .
-unicode_digit = /* a Unicode code point classified as "Number, decimal digit" */ .
-
-
-Letters and digits
-
-_ (U+005F) is considered a letter.
-
-letter = unicode_letter | "_" .
-decimal_digit = "0" … "9" .
-binary_digit = "0" | "1" .
-octal_digit = "0" … "7" .
-hex_digit = "0" … "9" | "A" … "F" | "a" … "f" .
-
-
-Lexical elements
-
-Comments
-
-
-
-
-//
-and stop at the end of the line.
-/*
-and stop with the first subsequent character sequence */.
-Tokens
-
-Semicolons
-
-";" as terminators in
-a number of productions. Go programs may omit most of these semicolons
-using the following two rules:
-
-
-
-
-
-break,
- continue,
- fallthrough, or
- return
- ++,
- --,
- ),
- ], or
- }
- ")" or "}".
-Identifiers
-
-
-identifier = letter { letter | unicode_digit } .
-
-
-a
-_x9
-ThisVariableIsExported
-αβ
-
-
-Keywords
-
-
-break default func interface select
-case defer go map struct
-chan else goto package switch
-const fallthrough if range type
-continue for import return var
-
-
-Operators and punctuation
-
-
-+ & += &= && == != ( )
-- | -= |= || < <= [ ]
-* ^ *= ^= <- > >= { }
-/ << /= <<= ++ = := , ;
-% >> %= >>= -- ! ... . :
- &^ &^=
-
-
-Integer literals
-
-0b or 0B
-for binary, 0, 0o, or 0O for octal,
-and 0x or 0X for hexadecimal.
-A single 0 is considered a decimal zero.
-In hexadecimal literals, letters a through f
-and A through F represent values 10 through 15.
-_ may appear after
-a base prefix or between successive digits; such underscores do not change
-the literal's value.
-
-int_lit = decimal_lit | binary_lit | octal_lit | hex_lit .
-decimal_lit = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] .
-binary_lit = "0" ( "b" | "B" ) [ "_" ] binary_digits .
-octal_lit = "0" [ "o" | "O" ] [ "_" ] octal_digits .
-hex_lit = "0" ( "x" | "X" ) [ "_" ] hex_digits .
-
-decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
-binary_digits = binary_digit { [ "_" ] binary_digit } .
-octal_digits = octal_digit { [ "_" ] octal_digit } .
-hex_digits = hex_digit { [ "_" ] hex_digit } .
-
-
-
-42
-4_2
-0600
-0_600
-0o600
-0O600 // second character is capital letter 'O'
-0xBadFace
-0xBad_Face
-0x_67_7a_2f_cc_40_c6
-170141183460469231731687303715884105727
-170_141183_460469_231731_687303_715884_105727
-
-_42 // an identifier, not an integer literal
-42_ // invalid: _ must separate successive digits
-4__2 // invalid: only one _ at a time
-0_xBadFace // invalid: _ must separate successive digits
-
-
-
-Floating-point literals
-
-e or E followed by an optional sign and decimal digits).
-One of the integer part or the fractional part may be elided; one of the decimal point
-or the exponent part may be elided.
-An exponent value exp scales the mantissa (integer and fractional part) by 10exp.
-0x or 0X
-prefix, an integer part (hexadecimal digits), a radix point, a fractional part (hexadecimal digits),
-and an exponent part (p or P followed by an optional sign and decimal digits).
-One of the integer part or the fractional part may be elided; the radix point may be elided as well,
-but the exponent part is required. (This syntax matches the one given in IEEE 754-2008 §5.12.3.)
-An exponent value exp scales the mantissa (integer and fractional part) by 2exp.
-_ may appear after
-a base prefix or between successive digits; such underscores do not change
-the literal value.
-
-float_lit = decimal_float_lit | hex_float_lit .
-
-decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
- decimal_digits decimal_exponent |
- "." decimal_digits [ decimal_exponent ] .
-decimal_exponent = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
-
-hex_float_lit = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
-hex_mantissa = [ "_" ] hex_digits "." [ hex_digits ] |
- [ "_" ] hex_digits |
- "." hex_digits .
-hex_exponent = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
-
-
-
-0.
-72.40
-072.40 // == 72.40
-2.71828
-1.e+0
-6.67428e-11
-1E6
-.25
-.12345E+5
-1_5. // == 15.0
-0.15e+0_2 // == 15.0
-
-0x1p-2 // == 0.25
-0x2.p10 // == 2048.0
-0x1.Fp+0 // == 1.9375
-0X.8p-0 // == 0.5
-0X_1FFFP-16 // == 0.1249847412109375
-0x15e-2 // == 0x15e - 2 (integer subtraction)
-
-0x.p1 // invalid: mantissa has no digits
-1p-2 // invalid: p exponent requires hexadecimal mantissa
-0x1.5e-2 // invalid: hexadecimal mantissa requires p exponent
-1_.5 // invalid: _ must separate successive digits
-1._5 // invalid: _ must separate successive digits
-1.5_e1 // invalid: _ must separate successive digits
-1.5e_1 // invalid: _ must separate successive digits
-1.5e1_ // invalid: _ must separate successive digits
-
-
-
-Imaginary literals
-
-i.
-The value of an imaginary literal is the value of the respective
-integer or floating-point literal multiplied by the imaginary unit i.
-
-imaginary_lit = (decimal_digits | int_lit | float_lit) "i" .
-
-
-0.
-
-0i
-0123i // == 123i for backward-compatibility
-0o123i // == 0o123 * 1i == 83i
-0xabci // == 0xabc * 1i == 2748i
-0.i
-2.71828i
-1.e+0i
-6.67428e-11i
-1E6i
-.25i
-.12345E+5i
-0x1p-2i // == 0x1p-2 * 1i == 0.25i
-
-
-
-Rune literals
-
-'x' or '\n'.
-Within the quotes, any character may appear except newline and unescaped single
-quote. A single quoted character represents the Unicode value
-of the character itself,
-while multi-character sequences beginning with a backslash encode
-values in various formats.
-'a' holds a single byte representing
-a literal a, Unicode U+0061, value 0x61, while
-'ä' holds two bytes (0xc3 0xa4) representing
-a literal a-dieresis, U+00E4, value 0xe4.
-\x followed by exactly two hexadecimal
-digits; \u followed by exactly four hexadecimal digits;
-\U followed by exactly eight hexadecimal digits, and a
-plain backslash \ followed by exactly three octal digits.
-In each case the value of the literal is the value represented by
-the digits in the corresponding base.
-\u and \U
-represent Unicode code points so within them some values are illegal,
-in particular those above 0x10FFFF and surrogate halves.
-
-\a U+0007 alert or bell
-\b U+0008 backspace
-\f U+000C form feed
-\n U+000A line feed or newline
-\r U+000D carriage return
-\t U+0009 horizontal tab
-\v U+000B vertical tab
-\\ U+005C backslash
-\' U+0027 single quote (valid escape only within rune literals)
-\" U+0022 double quote (valid escape only within string literals)
-
-
-
-rune_lit = "'" ( unicode_value | byte_value ) "'" .
-unicode_value = unicode_char | little_u_value | big_u_value | escaped_char .
-byte_value = octal_byte_value | hex_byte_value .
-octal_byte_value = `\` octal_digit octal_digit octal_digit .
-hex_byte_value = `\` "x" hex_digit hex_digit .
-little_u_value = `\` "u" hex_digit hex_digit hex_digit hex_digit .
-big_u_value = `\` "U" hex_digit hex_digit hex_digit hex_digit
- hex_digit hex_digit hex_digit hex_digit .
-escaped_char = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
-
-
-
-'a'
-'ä'
-'本'
-'\t'
-'\000'
-'\007'
-'\377'
-'\x07'
-'\xff'
-'\u12e4'
-'\U00101234'
-'\'' // rune literal containing single quote character
-'aa' // illegal: too many characters
-'\xa' // illegal: too few hexadecimal digits
-'\0' // illegal: too few octal digits
-'\uDFFF' // illegal: surrogate half
-'\U00110000' // illegal: invalid Unicode code point
-
-
-
-String literals
-
-`foo`. Within the quotes, any character may appear except
-back quote. The value of a raw string literal is the
-string composed of the uninterpreted (implicitly UTF-8-encoded) characters
-between the quotes;
-in particular, backslashes have no special meaning and the string may
-contain newlines.
-Carriage return characters ('\r') inside raw string literals
-are discarded from the raw string value.
-"bar".
-Within the quotes, any character may appear except newline and unescaped double quote.
-The text between the quotes forms the
-value of the literal, with backslash escapes interpreted as they
-are in rune literals (except that \' is illegal and
-\" is legal), with the same restrictions.
-The three-digit octal (\nnn)
-and two-digit hexadecimal (\xnn) escapes represent individual
-bytes of the resulting string; all other escapes represent
-the (possibly multi-byte) UTF-8 encoding of individual characters.
-Thus inside a string literal \377 and \xFF represent
-a single byte of value 0xFF=255, while ÿ,
-\u00FF, \U000000FF and \xc3\xbf represent
-the two bytes 0xc3 0xbf of the UTF-8 encoding of character
-U+00FF.
-
-string_lit = raw_string_lit | interpreted_string_lit .
-raw_string_lit = "`" { unicode_char | newline } "`" .
-interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
-
-
-
-`abc` // same as "abc"
-`\n
-\n` // same as "\\n\n\\n"
-"\n"
-"\"" // same as `"`
-"Hello, world!\n"
-"日本語"
-"\u65e5本\U00008a9e"
-"\xff\u00FF"
-"\uD800" // illegal: surrogate half
-"\U00110000" // illegal: invalid Unicode code point
-
-
-
-"日本語" // UTF-8 input text
-`日本語` // UTF-8 input text as a raw literal
-"\u65e5\u672c\u8a9e" // the explicit Unicode code points
-"\U000065e5\U0000672c\U00008a9e" // the explicit Unicode code points
-"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // the explicit UTF-8 bytes
-
-
-Constants
-
-unsafe.Sizeof applied to any value,
-cap or len applied to
-some expressions,
-real and imag applied to a complex constant
-and complex applied to numeric constants.
-The boolean truth values are represented by the predeclared constants
-true and false. The predeclared identifier
-iota denotes an integer constant.
-true, false, iota,
-and certain constant expressions
-containing only untyped constant operands are untyped.
-i := 0 where there is no explicit type.
-The default type of an untyped constant is bool, rune,
-int, float64, complex128 or string
-respectively, depending on whether it is a boolean, rune, integer, floating-point,
-complex, or string constant.
-
-
-
-Variables
-
-new
-or taking the address of a composite literal
-allocates storage for a variable at run time.
-Such an anonymous variable is referred to via a (possibly implicit)
-pointer indirection.
-new call or composite literal, or the type of
-an element of a structured variable.
-Variables of interface type also have a distinct dynamic type,
-which is the concrete type of the value assigned to the variable at run time
-(unless the value is the predeclared identifier nil,
-which has no type).
-The dynamic type may vary during execution but values stored in interface
-variables are always assignable
-to the static type of the variable.
-
-var x interface{} // x is nil and has static type interface{}
-var v *T // v has value nil, static type *T
-x = 42 // x has value 42 and dynamic type int
-x = v // x has value (*T)(nil) and dynamic type *T
-
-
-Types
-
-
-Type = TypeName | TypeLit | "(" Type ")" .
-TypeName = identifier | QualifiedIdent .
-TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
- SliceType | MapType | ChannelType .
-
-
-T has an underlying type: If T
-is one of the predeclared boolean, numeric, or string types, or a type literal,
-the corresponding underlying
-type is T itself. Otherwise, T's underlying type
-is the underlying type of the type to which T refers in its
-type declaration.
-
-type (
- A1 = string
- A2 = A1
-)
-
-type (
- B1 string
- B2 B1
- B3 []B1
- B4 B3
-)
-
-
-string, A1, A2, B1,
-and B2 is string.
-The underlying type of []B1, B3, and B4 is []B1.
-Method sets
-T consists of all
-methods declared with receiver type T.
-The method set of the corresponding pointer type *T
-is the set of all methods declared with receiver *T or T
-(that is, it also contains the method set of T).
-Further rules apply to structs containing embedded fields, as described
-in the section on struct types.
-Any other type has an empty method set.
-In a method set, each method must have a
-unique
-non-blank method name.
-Boolean types
-
-true
-and false. The predeclared boolean type is bool;
-it is a defined type.
-Numeric types
-
-
-uint8 the set of all unsigned 8-bit integers (0 to 255)
-uint16 the set of all unsigned 16-bit integers (0 to 65535)
-uint32 the set of all unsigned 32-bit integers (0 to 4294967295)
-uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615)
-
-int8 the set of all signed 8-bit integers (-128 to 127)
-int16 the set of all signed 16-bit integers (-32768 to 32767)
-int32 the set of all signed 32-bit integers (-2147483648 to 2147483647)
-int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
-
-float32 the set of all IEEE 754 32-bit floating-point numbers
-float64 the set of all IEEE 754 64-bit floating-point numbers
-
-complex64 the set of all complex numbers with float32 real and imaginary parts
-complex128 the set of all complex numbers with float64 real and imaginary parts
-
-byte alias for uint8
-rune alias for int32
-
-
-
-uint either 32 or 64 bits
-int same size as uint
-uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value
-
-
-byte, which is an alias for uint8, and
-rune, which is an alias for int32.
-Explicit conversions
-are required when different numeric types are mixed in an expression
-or assignment. For instance, int32 and int
-are not the same type even though they may have the same size on a
-particular architecture.
-String types
-
-string;
-it is a defined type.
-s can be discovered using
-the built-in function len.
-The length is a compile-time constant if the string is a constant.
-A string's bytes can be accessed by integer indices
-0 through len(s)-1.
-It is illegal to take the address of such an element; if
-s[i] is the i'th byte of a
-string, &s[i] is invalid.
-Array types
-
-
-ArrayType = "[" ArrayLength "]" ElementType .
-ArrayLength = Expression .
-ElementType = Type .
-
-
-int.
-The length of array a can be discovered
-using the built-in function len.
-The elements can be addressed by integer indices
-0 through len(a)-1.
-Array types are always one-dimensional but may be composed to form
-multi-dimensional types.
-
-[32]byte
-[2*N] struct { x, y int32 }
-[1000]*float64
-[3][5]int
-[2][2][2]float64 // same as [2]([2]([2]float64))
-
-
-Slice types
-
-nil.
-
-SliceType = "[" "]" ElementType .
-
-
-s can be discovered by the built-in function
-len; unlike with arrays it may change during
-execution. The elements can be addressed by integer indices
-0 through len(s)-1. The slice index of a
-given element may be less than the index of the same element in the
-underlying array.
-a can be discovered using the
-built-in function cap(a).
-T is
-made using the built-in function
-make,
-which takes a slice type
-and parameters specifying the length and optionally the capacity.
-A slice created with make always allocates a new, hidden array
-to which the returned slice value refers. That is, executing
-
-make([]T, length, capacity)
-
-
-
-make([]int, 50, 100)
-new([100]int)[0:50]
-
-
-Struct types
-
-
-StructType = "struct" "{" { FieldDecl ";" } "}" .
-FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] .
-EmbeddedField = [ "*" ] TypeName .
-Tag = string_lit .
-
-
-
-// An empty struct.
-struct {}
-
-// A struct with 6 fields.
-struct {
- x, y int
- u float32
- _ float32 // padding
- A *[]int
- F func()
-}
-
-
-T or as a pointer to a non-interface type name *T,
-and T itself may not be
-a pointer type. The unqualified type name acts as the field name.
-
-// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4
-struct {
- T1 // field name is T1
- *T2 // field name is T2
- P.T3 // field name is T3
- *P.T4 // field name is T4
- x, y int // field names are x and y
-}
-
-
-
-struct {
- T // conflicts with embedded field *T and *P.T
- *T // conflicts with embedded field T and *P.T
- *P.T // conflicts with embedded field T and *T
-}
-
-
-f of an
-embedded field in a struct x is called promoted if
-x.f is a legal selector that denotes
-that field or method f.
-S and a defined type
-T, promoted methods are included in the method set of the struct as follows:
-
-
-
-S contains an embedded field T,
- the method sets of S
- and *S both include promoted methods with receiver
- T. The method set of *S also
- includes promoted methods with receiver *T.
- S contains an embedded field *T,
- the method sets of S and *S both
- include promoted methods with receiver T or
- *T.
-
-struct {
- x, y float64 "" // an empty tag string is like an absent tag
- name string "any string is permitted as a tag"
- _ [4]byte "ceci n'est pas un champ de structure"
-}
-
-// A struct corresponding to a TimeStamp protocol buffer.
-// The tag strings define the protocol buffer field numbers;
-// they follow the convention outlined by the reflect package.
-struct {
- microsec uint64 `protobuf:"1"`
- serverIP6 uint64 `protobuf:"2"`
-}
-
-
-Pointer types
-
-nil.
-
-PointerType = "*" BaseType .
-BaseType = Type .
-
-
-
-*Point
-*[4]int
-
-
-Function types
-
-nil.
-
-FunctionType = "func" Signature .
-Signature = Parameters [ Result ] .
-Result = Parameters | Type .
-Parameters = "(" [ ParameterList [ "," ] ] ")" .
-ParameterList = ParameterDecl { "," ParameterDecl } .
-ParameterDecl = [ IdentifierList ] [ "..." ] Type .
-
-
-....
-A function with such a parameter is called variadic and
-may be invoked with zero or more arguments for that parameter.
-
-func()
-func(x int) int
-func(a, _ int, z float32) bool
-func(a, b int, z float32) (bool)
-func(prefix string, values ...int)
-func(a, b int, z float64, opt ...interface{}) (success bool)
-func(int, int, float64) (float64, *[]int)
-func(n int) func(p *T)
-
-
-
-Interface types
-
-nil.
-
-InterfaceType = "interface" "{" { ( MethodSpec | InterfaceTypeName ) ";" } "}" .
-MethodSpec = MethodName Signature .
-MethodName = identifier .
-InterfaceTypeName = TypeName .
-
-
-
-// A simple File interface.
-interface {
- Read([]byte) (int, error)
- Write([]byte) (int, error)
- Close() error
-}
-
-
-
-interface {
- String() string
- String() string // illegal: String not unique
- _(x int) // illegal: method must have non-blank name
-}
-
-
-S1 and S2
-have the method set
-
-func (p T) Read(p []byte) (n int, err error)
-func (p T) Write(p []byte) (n int, err error)
-func (p T) Close() error
-
-
-T stands for either S1 or S2)
-then the File interface is implemented by both S1 and
-S2, regardless of what other methods
-S1 and S2 may have or share.
-
-interface{}
-
-
-Locker:
-
-type Locker interface {
- Lock()
- Unlock()
-}
-
-
-S1 and S2 also implement
-
-func (p T) Lock() { … }
-func (p T) Unlock() { … }
-
-
-Locker interface as well
-as the File interface.
-T may use a (possibly qualified) interface type
-name E in place of a method specification. This is called
-embedding interface E in T.
-The method set of T is the union
-of the method sets of T’s explicitly declared methods and of
-T’s embedded interfaces.
-
-type Reader interface {
- Read(p []byte) (n int, err error)
- Close() error
-}
-
-type Writer interface {
- Write(p []byte) (n int, err error)
- Close() error
-}
-
-// ReadWriter's methods are Read, Write, and Close.
-type ReadWriter interface {
- Reader // includes methods of Reader in ReadWriter's method set
- Writer // includes methods of Writer in ReadWriter's method set
-}
-
-
-
-type ReadCloser interface {
- Reader // includes methods of Reader in ReadCloser's method set
- Close() // illegal: signatures of Reader.Close and Close are different
-}
-
-
-T may not embed itself
-or any interface type that embeds T, recursively.
-
-// illegal: Bad cannot embed itself
-type Bad interface {
- Bad
-}
-
-// illegal: Bad1 cannot embed itself using Bad2
-type Bad1 interface {
- Bad2
-}
-type Bad2 interface {
- Bad1
-}
-
-
-Map types
-
-nil.
-
-MapType = "map" "[" KeyType "]" ElementType .
-KeyType = Type .
-
-
-== and != must be fully defined
-for operands of the key type; thus the key type must not be a function, map, or
-slice.
-If the key type is an interface type, these
-comparison operators must be defined for the dynamic key values;
-failure will cause a run-time panic.
-
-
-map[string]int
-map[*T]struct{ x, y float64 }
-map[string]interface{}
-
-
-m, it can be discovered using the
-built-in function len
-and may change during execution. Elements may be added during execution
-using assignments and retrieved with
-index expressions; they may be removed with the
-delete built-in function.
-make,
-which takes the map type and an optional capacity hint as arguments:
-
-make(map[string]int)
-make(map[string]int, 100)
-
-
-nil maps.
-A nil map is equivalent to an empty map except that no elements
-may be added.
-Channel types
-
-nil.
-
-ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
-
-
-<- operator specifies the channel direction,
-send or receive. If no direction is given, the channel is
-bidirectional.
-A channel may be constrained only to send or only to receive by
-assignment or
-explicit conversion.
-
-chan T // can be used to send and receive values of type T
-chan<- float64 // can only be used to send float64s
-<-chan int // can only be used to receive ints
-
-
-<- operator associates with the leftmost chan
-possible:
-
-chan<- chan int // same as chan<- (chan int)
-chan<- <-chan int // same as chan<- (<-chan int)
-<-chan <-chan int // same as <-chan (<-chan int)
-chan (<-chan int)
-
-
-make,
-which takes the channel type and an optional capacity as arguments:
-
-make(chan int, 100)
-
-
-nil channel is never ready for communication.
-close.
-The multi-valued assignment form of the
-receive operator
-reports whether a received value was sent before
-the channel was closed.
-cap and
-len
-by any number of goroutines without further synchronization.
-Channels act as first-in-first-out queues.
-For example, if one goroutine sends values on a channel
-and a second goroutine receives them, the values are
-received in the order sent.
-Properties of types and values
-
-Type identity
-
-
-
-
-
-type (
- A0 = []string
- A1 = A0
- A2 = struct{ a, b int }
- A3 = int
- A4 = func(A3, float64) *A0
- A5 = func(x int, _ float64) *[]string
-)
-
-type (
- B0 A0
- B1 []string
- B2 struct{ a, b int }
- B3 struct{ a, c int }
- B4 func(int, float64) *B0
- B5 func(x int, y float64) *A1
-)
-
-type C0 = B0
-
-
-
-A0, A1, and []string
-A2 and struct{ a, b int }
-A3 and int
-A4, func(int, float64) *[]string, and A5
-
-B0 and C0
-[]int and []int
-struct{ a, b *T5 } and struct{ a, b *T5 }
-func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
-
-
-B0 and B1 are different because they are new types
-created by distinct type definitions;
-func(int, float64) *B0 and func(x int, y float64) *[]string
-are different because B0 is different from []string.
-Assignability
-
-x is assignable to a variable of type T
-("x is assignable to T") if one of the following conditions applies:
-
-
-
-
-x's type is identical to T.
-x's type V and T have identical
-underlying types and at least one of V
-or T is not a defined type.
-T is an interface type and
-x implements T.
-x is a bidirectional channel value, T is a channel type,
-x's type V and T have identical element types,
-and at least one of V or T is not a defined type.
-x is the predeclared identifier nil and T
-is a pointer, function, slice, map, channel, or interface type.
-x is an untyped constant
-representable
-by a value of type T.
-Representability
-
-x is representable
-by a value of type T if one of the following conditions applies:
-
-
-
-x is in the set of values determined by T.
-T is a floating-point type and x can be rounded to T's
-precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE
-negative zero further simplified to an unsigned zero. Note that constant values never result
-in an IEEE negative zero, NaN, or infinity.
-T is a complex type, and x's
-components real(x) and imag(x)
-are representable by values of T's component type (float32 or
-float64).
-
-x T x is representable by a value of T because
-
-'a' byte 97 is in the set of byte values
-97 rune rune is an alias for int32, and 97 is in the set of 32-bit integers
-"foo" string "foo" is in the set of string values
-1024 int16 1024 is in the set of 16-bit integers
-42.0 byte 42 is in the set of unsigned 8-bit integers
-1e10 uint64 10000000000 is in the set of unsigned 64-bit integers
-2.718281828459045 float32 2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
--1e-1000 float64 -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
-0i int 0 is an integer value
-(42 + 0i) float32 42.0 (with zero imaginary part) is in the set of float32 values
-
-
-
-x T x is not representable by a value of T because
-
-0 bool 0 is not in the set of boolean values
-'a' string 'a' is a rune, it is not in the set of string values
-1024 byte 1024 is not in the set of unsigned 8-bit integers
--1 uint16 -1 is not in the set of unsigned 16-bit integers
-1.1 int 1.1 is not an integer value
-42i float32 (0 + 42i) is not in the set of float32 values
-1e1000 float64 1e1000 overflows to IEEE +Inf after rounding
-
-
-
-Blocks
-
-
-Block = "{" StatementList "}" .
-StatementList = { Statement ";" } .
-
-
-
-
-
-Declarations and scope
-
-init may only be used for
-init function declarations,
-and like the blank identifier it does not introduce a new binding.
-
-Declaration = ConstDecl | TypeDecl | VarDecl .
-TopLevelDecl = Declaration | FunctionDecl | MethodDecl .
-
-
-
-
-
-Label scopes
-
-Blank identifier
-
-_.
-It serves as an anonymous placeholder instead of a regular (non-blank)
-identifier and has special meaning in declarations,
-as an operand, and in assignments.
-Predeclared identifiers
-
-
-Types:
- bool byte complex64 complex128 error float32 float64
- int int8 int16 int32 int64 rune string
- uint uint8 uint16 uint32 uint64 uintptr
-
-Constants:
- true false iota
-
-Zero value:
- nil
-
-Functions:
- append cap close complex copy delete imag len
- make new panic print println real recover
-
-
-
-Exported identifiers
-
-
-
-Uniqueness of identifiers
-
-Constant declarations
-
-
-ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
-ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
-
-IdentifierList = identifier { "," identifier } .
-ExpressionList = Expression { "," Expression } .
-
-
-
-const Pi float64 = 3.14159265358979323846
-const zero = 0.0 // untyped floating-point constant
-const (
- size int64 = 1024
- eof = -1 // untyped integer constant
-)
-const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", untyped integer and string constants
-const u, v float32 = 0, 3 // u = 0.0, v = 3.0
-
-
-const declaration list the
-expression list may be omitted from any but the first ConstSpec.
-Such an empty list is equivalent to the textual substitution of the
-first preceding non-empty expression list and its type if any.
-Omitting the list of expressions is therefore equivalent to
-repeating the previous list. The number of identifiers must be equal
-to the number of expressions in the previous list.
-Together with the iota constant generator
-this mechanism permits light-weight declaration of sequential values:
-
-const (
- Sunday = iota
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Partyday
- numberOfDays // this constant is not exported
-)
-
-
-
-Iota
-
-iota represents successive untyped integer
-constants. Its value is the index of the respective ConstSpec
-in that constant declaration, starting at zero.
-It can be used to construct a set of related constants:
-
-const (
- c0 = iota // c0 == 0
- c1 = iota // c1 == 1
- c2 = iota // c2 == 2
-)
-
-const (
- a = 1 << iota // a == 1 (iota == 0)
- b = 1 << iota // b == 2 (iota == 1)
- c = 3 // c == 3 (iota == 2, unused)
- d = 1 << iota // d == 8 (iota == 3)
-)
-
-const (
- u = iota * 42 // u == 0 (untyped integer constant)
- v float64 = iota * 42 // v == 42.0 (float64 constant)
- w = iota * 42 // w == 84 (untyped integer constant)
-)
-
-const x = iota // x == 0
-const y = iota // y == 0
-
-
-iota in the same ConstSpec all have the same value:
-
-const (
- bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0 (iota == 0)
- bit1, mask1 // bit1 == 2, mask1 == 1 (iota == 1)
- _, _ // (iota == 2, unused)
- bit3, mask3 // bit3 == 8, mask3 == 7 (iota == 3)
-)
-
-
-Type declarations
-
-
-TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
-TypeSpec = AliasDecl | TypeDef .
-
-
-Alias declarations
-
-
-AliasDecl = identifier "=" Type .
-
-
-
-type (
- nodeList = []*Node // nodeList and []*Node are identical types
- Polar = polar // Polar and polar denote identical types
-)
-
-
-
-Type definitions
-
-
-TypeDef = identifier Type .
-
-
-
-type (
- Point struct{ x, y float64 } // Point and struct{ x, y float64 } are different types
- polar Point // polar and Point denote different types
-)
-
-type TreeNode struct {
- left, right *TreeNode
- value *Comparable
-}
-
-type Block interface {
- BlockSize() int
- Encrypt(src, dst []byte)
- Decrypt(src, dst []byte)
-}
-
-
-
-// A Mutex is a data type with two methods, Lock and Unlock.
-type Mutex struct { /* Mutex fields */ }
-func (m *Mutex) Lock() { /* Lock implementation */ }
-func (m *Mutex) Unlock() { /* Unlock implementation */ }
-
-// NewMutex has the same composition as Mutex but its method set is empty.
-type NewMutex Mutex
-
-// The method set of PtrMutex's underlying type *Mutex remains unchanged,
-// but the method set of PtrMutex is empty.
-type PtrMutex *Mutex
-
-// The method set of *PrintableMutex contains the methods
-// Lock and Unlock bound to its embedded field Mutex.
-type PrintableMutex struct {
- Mutex
-}
-
-// MyBlock is an interface type that has the same method set as Block.
-type MyBlock Block
-
-
-
-type TimeZone int
-
-const (
- EST TimeZone = -(5 + iota)
- CST
- MST
- PST
-)
-
-func (tz TimeZone) String() string {
- return fmt.Sprintf("GMT%+dh", tz)
-}
-
-
-
-Variable declarations
-
-
-VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
-VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
-
-
-
-var i int
-var U, V, W float64
-var k = 0
-var x, y float32 = -1, -2
-var (
- i int
- u, v, s = 2.0, 3.0, "bar"
-)
-var re, im = complexSqrt(-1)
-var _, found = entries[name] // map lookup; only interested in "found"
-
-
-bool.
-The predeclared value nil cannot be used to initialize a variable
-with no explicit type.
-
-var d = math.Sin(0.5) // d is float64
-var i = 42 // i is int
-var t, ok = x.(T) // t is T, ok is bool
-var n = nil // illegal
-
-
-Short variable declarations
-
-
-ShortVarDecl = IdentifierList ":=" ExpressionList .
-
-
-
-"var" IdentifierList = ExpressionList .
-
-
-
-i, j := 0, 10
-f := func() int { return 7 }
-ch := make(chan int)
-r, w, _ := os.Pipe() // os.Pipe() returns a connected pair of Files and an error, if any
-_, y, _ := coord(p) // coord() returns three values; only interested in y coordinate
-
-
-
-field1, offset := nextField(str, 0)
-field2, offset := nextField(str, offset) // redeclares offset
-a, a := 1, 2 // illegal: double declaration of a or no new variable if a was declared elsewhere
-
-
-Function declarations
-
-
-FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
-FunctionName = identifier .
-FunctionBody = Block .
-
-
-
-func IndexRune(s string, r rune) int {
- for i, c := range s {
- if c == r {
- return i
- }
- }
- // invalid: missing return statement
-}
-
-
-
-func min(x int, y int) int {
- if x < y {
- return x
- }
- return y
-}
-
-func flushICache(begin, end uintptr) // implemented externally
-
-
-Method declarations
-
-
-MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
-Receiver = Parameters .
-
-
-T or a
-pointer to a defined type T. T is called the receiver
-base type. A receiver base type cannot be a pointer or interface type and
-it must be defined in the same package as the method.
-The method is said to be bound to its receiver base type and the method name
-is visible only within selectors for type T
-or *T.
-Point, the declarations
-
-func (p *Point) Length() float64 {
- return math.Sqrt(p.x * p.x + p.y * p.y)
-}
-
-func (p *Point) Scale(factor float64) {
- p.x *= factor
- p.y *= factor
-}
-
-
-Length and Scale,
-with receiver type *Point,
-to the base type Point.
-Scale has type
-
-func(p *Point, factor float64)
-
-
-Expressions
-
-Operands
-
-
-Operand = Literal | OperandName | "(" Expression ")" .
-Literal = BasicLit | CompositeLit | FunctionLit .
-BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
-OperandName = identifier | QualifiedIdent .
-
-
-Qualified identifiers
-
-
-QualifiedIdent = PackageName "." identifier .
-
-
-
-math.Sin // denotes the Sin function in package math
-
-
-Composite literals
-
-
-CompositeLit = LiteralType LiteralValue .
-LiteralType = StructType | ArrayType | "[" "..." "]" ElementType |
- SliceType | MapType | TypeName .
-LiteralValue = "{" [ ElementList [ "," ] ] "}" .
-ElementList = KeyedElement { "," KeyedElement } .
-KeyedElement = [ Key ":" ] Element .
-Key = FieldName | Expression | LiteralValue .
-FieldName = identifier .
-Element = Expression | LiteralValue .
-
-
-
-
-
-
-type Point3D struct { x, y, z float64 }
-type Line struct { p, q Point3D }
-
-
-
-origin := Point3D{} // zero value for Point3D
-line := Line{origin, Point3D{y: -4, z: 12.3}} // zero value for line.q.x
-
-
-
-
-
-int; and if it is typed
- it must be of integer type.
-
-var pointer *Point3D = &Point3D{y: 1000}
-
-
-
-p1 := &[]int{} // p1 points to an initialized, empty slice with value []int{} and length 0
-p2 := new([]int) // p2 points to an uninitialized slice with value nil and length 0
-
-
-... specifies an array length equal
-to the maximum element index plus one.
-
-buffer := [10]string{} // len(buffer) == 10
-intSet := [6]int{1, 2, 3, 5} // len(intSet) == 6
-days := [...]string{"Sat", "Sun"} // len(days) == 2
-
-
-
-[]T{x1, x2, … xn}
-
-
-
-tmp := [n]T{x1, x2, … xn}
-tmp[0 : n]
-
-
-T,
-elements or map keys that are themselves composite literals may elide the respective
-literal type if it is identical to the element or key type of T.
-Similarly, elements or keys that are addresses of composite literals may elide
-the &T when the element or key type is *T.
-
-[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}
-[][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}
-[][]Point{{{0, 1}, {1, 2}}} // same as [][]Point{[]Point{Point{0, 1}, Point{1, 2}}}
-map[string]Point{"orig": {0, 0}} // same as map[string]Point{"orig": Point{0, 0}}
-map[Point]string{{0, 0}: "orig"} // same as map[Point]string{Point{0, 0}: "orig"}
-
-type PPoint *Point
-[2]*Point{{1.5, -3.5}, {}} // same as [2]*Point{&Point{1.5, -3.5}, &Point{}}
-[2]PPoint{{1.5, -3.5}, {}} // same as [2]PPoint{PPoint(&Point{1.5, -3.5}), PPoint(&Point{})}
-
-
-
-if x == (T{a,b,c}[i]) { … }
-if (x == T{a,b,c}[i]) { … }
-
-
-
-// list of prime numbers
-primes := []int{2, 3, 5, 7, 9, 2147483647}
-
-// vowels[ch] is true if ch is a vowel
-vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
-
-// the array [10]float32{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1}
-filter := [10]float32{-1, 4: -0.1, -0.1, 9: -1}
-
-// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
-noteFrequency := map[string]float32{
- "C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
- "G0": 24.50, "A0": 27.50, "B0": 30.87,
-}
-
-
-
-Function literals
-
-
-FunctionLit = "func" Signature FunctionBody .
-
-
-
-func(a, b int, z float64) bool { return a*b < int(z) }
-
-
-
-f := func(x, y int) int { return x + y }
-func(ch chan int) { ch <- ACK }(replyChan)
-
-
-Primary expressions
-
-
-PrimaryExpr =
- Operand |
- Conversion |
- MethodExpr |
- PrimaryExpr Selector |
- PrimaryExpr Index |
- PrimaryExpr Slice |
- PrimaryExpr TypeAssertion |
- PrimaryExpr Arguments .
-
-Selector = "." identifier .
-Index = "[" Expression "]" .
-Slice = "[" [ Expression ] ":" [ Expression ] "]" |
- "[" [ Expression ] ":" Expression ":" Expression "]" .
-TypeAssertion = "." "(" Type ")" .
-Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
-
-
-
-
-x
-2
-(s + ".txt")
-f(3.1415, true)
-Point{1, 2}
-m["foo"]
-s[i : j + 1]
-obj.color
-f.p[i].x()
-
-
-
-Selectors
-
-x
-that is not a package name, the
-selector expression
-
-x.f
-
-
-f of the value x
-(or sometimes *x; see below).
-The identifier f is called the (field or method) selector;
-it must not be the blank identifier.
-The type of the selector expression is the type of f.
-If x is a package name, see the section on
-qualified identifiers.
-f may denote a field or method f of
-a type T, or it may refer
-to a field or method f of a nested
-embedded field of T.
-The number of embedded fields traversed
-to reach f is called its depth in T.
-The depth of a field or method f
-declared in T is zero.
-The depth of a field or method f declared in
-an embedded field A in T is the
-depth of f in A plus one.
-
-
-
-x of type T or *T
-where T is not a pointer or interface type,
-x.f denotes the field or method at the shallowest depth
-in T where there
-is such an f.
-If there is not exactly one f
-with shallowest depth, the selector expression is illegal.
-x of type I where I
-is an interface type, x.f denotes the actual method with name
-f of the dynamic value of x.
-If there is no method with name f in the
-method set of I, the selector
-expression is illegal.
-x is a defined
-pointer type and (*x).f is a valid selector expression denoting a field
-(but not a method), x.f is shorthand for (*x).f.
-x.f is illegal.
-x is of pointer type and has the value
-nil and x.f denotes a struct field,
-assigning to or evaluating x.f
-causes a run-time panic.
-x is of interface type and has the value
-nil, calling or
-evaluating the method x.f
-causes a run-time panic.
-
-type T0 struct {
- x int
-}
-
-func (*T0) M0()
-
-type T1 struct {
- y int
-}
-
-func (T1) M1()
-
-type T2 struct {
- z int
- T1
- *T0
-}
-
-func (*T2) M2()
-
-type Q *T2
-
-var t T2 // with t.T0 != nil
-var p *T2 // with p != nil and (*p).T0 != nil
-var q Q = p
-
-
-
-t.z // t.z
-t.y // t.T1.y
-t.x // (*t.T0).x
-
-p.z // (*p).z
-p.y // (*p).T1.y
-p.x // (*(*p).T0).x
-
-q.x // (*(*q).T0).x (*q).x is a valid field selector
-
-p.M0() // ((*p).T0).M0() M0 expects *T0 receiver
-p.M1() // ((*p).T1).M1() M1 expects T1 receiver
-p.M2() // p.M2() M2 expects *T2 receiver
-t.M2() // (&t).M2() M2 expects *T2 receiver, see section on Calls
-
-
-
-q.M0() // (*q).M0 is valid but not a field selector
-
-
-
-Method expressions
-
-M is in the method set of type T,
-T.M is a function that is callable as a regular function
-with the same arguments as M prefixed by an additional
-argument that is the receiver of the method.
-
-MethodExpr = ReceiverType "." MethodName .
-ReceiverType = Type .
-
-
-T with two methods,
-Mv, whose receiver is of type T, and
-Mp, whose receiver is of type *T.
-
-type T struct {
- a int
-}
-func (tv T) Mv(a int) int { return 0 } // value receiver
-func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver
-
-var t T
-
-
-
-T.Mv
-
-
-Mv but
-with an explicit receiver as its first argument; it has signature
-
-func(tv T, a int) int
-
-
-
-t.Mv(7)
-T.Mv(t, 7)
-(T).Mv(t, 7)
-f1 := T.Mv; f1(t, 7)
-f2 := (T).Mv; f2(t, 7)
-
-
-
-(*T).Mp
-
-
-Mp with signature
-
-func(tp *T, f float32) float32
-
-
-
-(*T).Mv
-
-
-Mv with signature
-
-func(tv *T, a int) int
-
-
-f := T.Mv, f is invoked
-as f(t, 7) not t.f(7).
-To construct a function that binds the receiver, use a
-function literal or
-method value.
-Method values
-
-x has static type T and
-M is in the method set of type T,
-x.M is called a method value.
-The method value x.M is a function value that is callable
-with the same arguments as a method call of x.M.
-The expression x is evaluated and saved during the evaluation of the
-method value; the saved copy is then used as the receiver in any calls,
-which may be executed later.
-
-type S struct { *T }
-type T int
-func (t T) M() { print(t) }
-
-t := new(T)
-s := S{T: t}
-f := t.M // receiver *t is evaluated and stored in f
-g := s.M // receiver *(s.T) is evaluated and stored in g
-*t = 42 // does not affect stored receivers in f and g
-
-
-T may be an interface or non-interface type.
-T with two methods,
-Mv, whose receiver is of type T, and
-Mp, whose receiver is of type *T.
-
-type T struct {
- a int
-}
-func (tv T) Mv(a int) int { return 0 } // value receiver
-func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver
-
-var t T
-var pt *T
-func makeT() T
-
-
-
-t.Mv
-
-
-
-func(int) int
-
-
-
-t.Mv(7)
-f := t.Mv; f(7)
-
-
-
-pt.Mp
-
-
-
-func(float32) float32
-
-
-pt.Mv is equivalent to (*pt).Mv.
-t.Mp is equivalent to (&t).Mp.
-
-f := t.Mv; f(7) // like t.Mv(7)
-f := pt.Mp; f(7) // like pt.Mp(7)
-f := pt.Mv; f(7) // like (*pt).Mv(7)
-f := t.Mp; f(7) // like (&t).Mp(7)
-f := makeT().Mp // invalid: result of makeT() is not addressable
-
-
-
-var i interface { M(int) } = myVal
-f := i.M; f(7) // like i.M(7)
-
-
-
-Index expressions
-
-
-a[x]
-
-
-a indexed by x.
-The value x is called the index or map key, respectively.
-The following rules apply:
-a is not a map:
-
-
-
-x must be of integer type or an untyped constantintintx is in range if 0 <= x < len(a),
- otherwise it is out of rangea of array type A:
-
-
-
-x is out of range at run time,
- a run-time panic occursa[x] is the array element at index x and the type of
- a[x] is the element type of Aa of pointer to array type:
-
-
-
-a[x] is shorthand for (*a)[x]a of slice type S:
-
-
-
-x is out of range at run time,
- a run-time panic occursa[x] is the slice element at index x and the type of
- a[x] is the element type of Sa of string type:
-
-
-
-a is also constantx is out of range at run time,
- a run-time panic occursa[x] is the non-constant byte value at index x and the type of
- a[x] is bytea[x] may not be assigned toa of map type M:
-
-
-
-x's type must be
- assignable
- to the key type of Mx,
- a[x] is the map element with key x
- and the type of a[x] is the element type of Mnil or does not contain such an entry,
- a[x] is the zero value
- for the element type of Ma[x] is illegal.
-a of type map[K]V
-used in an assignment or initialization of the special form
-
-v, ok = a[x]
-v, ok := a[x]
-var v, ok = a[x]
-
-
-ok is
-true if the key x is present in the map, and
-false otherwise.
-nil map causes a
-run-time panic.
-Slice expressions
-
-Simple slice expressions
-
-a, the primary expression
-
-a[low : high]
-
-
-low and
-high select which elements of operand a appear
-in the result. The result has indices starting at 0 and length equal to
-high - low.
-After slicing the array a
-
-a := [5]int{1, 2, 3, 4, 5}
-s := a[1:4]
-
-
-s has type []int, length 3, capacity 4, and elements
-
-s[0] == 2
-s[1] == 3
-s[2] == 4
-
-
-low
-index defaults to zero; a missing high index defaults to the length of the
-sliced operand:
-
-a[2:] // same as a[2 : len(a)]
-a[:3] // same as a[0 : 3]
-a[:] // same as a[0 : len(a)]
-
-
-a is a pointer to an array, a[low : high] is shorthand for
-(*a)[low : high].
-0 <= low <= high <= len(a),
-otherwise they are out of range.
-For slices, the upper index bound is the slice capacity cap(a) rather than the length.
-A constant index must be non-negative and
-representable by a value of type
-int; for arrays or constant strings, constant indices must also be in range.
-If both indices are constant, they must satisfy low <= high.
-If the indices are out of range at run time, a run-time panic occurs.
-string.
-If the sliced operand is an array, it must be addressable
-and the result of the slice operation is a slice with the same element type as the array.
-nil slice, the result
-is a nil slice. Otherwise, if the result is a slice, it shares its underlying
-array with the operand.
-
-var a [10]int
-s1 := a[3:7] // underlying array of s1 is array a; &s1[2] == &a[5]
-s2 := s1[1:4] // underlying array of s2 is underlying array of s1 which is array a; &s2[1] == &a[5]
-s2[1] = 42 // s2[1] == s1[2] == a[5] == 42; they all refer to the same underlying array element
-
-
-
-Full slice expressions
-
-a (but not a string), the primary expression
-
-a[low : high : max]
-
-
-a[low : high]. Additionally, it controls the resulting slice's capacity
-by setting it to max - low. Only the first index may be omitted; it defaults to 0.
-After slicing the array a
-
-a := [5]int{1, 2, 3, 4, 5}
-t := a[1:3:5]
-
-
-t has type []int, length 2, capacity 4, and elements
-
-t[0] == 2
-t[1] == 3
-
-
-a is a pointer to an array,
-a[low : high : max] is shorthand for (*a)[low : high : max].
-If the sliced operand is an array, it must be addressable.
-0 <= low <= high <= max <= cap(a),
-otherwise they are out of range.
-A constant index must be non-negative and
-representable by a value of type
-int; for arrays, constant indices must also be in range.
-If multiple indices are constant, the constants that are present must be in range relative to each
-other.
-If the indices are out of range at run time, a run-time panic occurs.
-Type assertions
-
-x of interface type
-and a type T, the primary expression
-
-x.(T)
-
-
-x is not nil
-and that the value stored in x is of type T.
-The notation x.(T) is called a type assertion.
-T is not an interface type, x.(T) asserts
-that the dynamic type of x is identical
-to the type T.
-In this case, T must implement the (interface) type of x;
-otherwise the type assertion is invalid since it is not possible for x
-to store a value of type T.
-If T is an interface type, x.(T) asserts that the dynamic type
-of x implements the interface T.
-x and its type is T. If the type assertion is false,
-a run-time panic occurs.
-In other words, even though the dynamic type of x
-is known only at run time, the type of x.(T) is
-known to be T in a correct program.
-
-var x interface{} = 7 // x has dynamic type int and value 7
-i := x.(int) // i has type int and value 7
-
-type I interface { m() }
-
-func f(y I) {
- s := y.(string) // illegal: string does not implement I (missing method m)
- r := y.(io.Reader) // r has type io.Reader and the dynamic type of y must implement both I and io.Reader
- …
-}
-
-
-
-v, ok = x.(T)
-v, ok := x.(T)
-var v, ok = x.(T)
-var v, ok interface{} = x.(T) // dynamic types of v and ok are T and bool
-
-
-ok is true
-if the assertion holds. Otherwise it is false and the value of v is
-the zero value for type T.
-No run-time panic occurs in this case.
-Calls
-
-f of function type
-F,
-
-f(a1, a2, … an)
-
-
-f with arguments a1, a2, … an.
-Except for one special case, arguments must be single-valued expressions
-assignable to the parameter types of
-F and are evaluated before the function is called.
-The type of the expression is the result type
-of F.
-A method invocation is similar but the method itself
-is specified as a selector upon a value of the receiver type for
-the method.
-
-math.Atan2(x, y) // function call
-var pt *Point
-pt.Scale(3.5) // method call with receiver pt
-
-
-nil function value
-causes a run-time panic.
-g are equal in number and individually
-assignable to the parameters of another function or method
-f, then the call f(g(parameters_of_g))
-will invoke f after binding the return values of
-g to the parameters of f in order. The call
-of f must contain no parameters other than the call of g,
-and g must have at least one return value.
-If f has a final ... parameter, it is
-assigned the return values of g that remain after
-assignment of regular parameters.
-
-func Split(s string, pos int) (string, string) {
- return s[0:pos], s[pos:]
-}
-
-func Join(s, t string) string {
- return s + t
-}
-
-if Join(Split(value, len(value)/2)) != value {
- log.Panic("test fails")
-}
-
-
-x.m() is valid if the method set
-of (the type of) x contains m and the
-argument list can be assigned to the parameter list of m.
-If x is addressable and &x's method
-set contains m, x.m() is shorthand
-for (&x).m():
-
-var p Point
-p.Scale(3.5)
-
-
-Passing arguments to
-
-... parametersf is variadic with a final
-parameter p of type ...T, then within f
-the type of p is equivalent to type []T.
-If f is invoked with no actual arguments for p,
-the value passed to p is nil.
-Otherwise, the value passed is a new slice
-of type []T with a new underlying array whose successive elements
-are the actual arguments, which all must be assignable
-to T. The length and capacity of the slice is therefore
-the number of arguments bound to p and may differ for each
-call site.
-
-func Greeting(prefix string, who ...string)
-Greeting("nobody")
-Greeting("hello:", "Joe", "Anna", "Eileen")
-
-
-Greeting, who will have the value
-nil in the first call, and
-[]string{"Joe", "Anna", "Eileen"} in the second.
-[]T and
-is followed by ..., it is passed unchanged as the value
-for a ...T parameter. In this case no new slice is created.
-s and call
-
-s := []string{"James", "Jasmine"}
-Greeting("goodbye:", s...)
-
-
-Greeting, who will have the same value as s
-with the same underlying array.
-Operators
-
-
-Expression = UnaryExpr | Expression binary_op Expression .
-UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
-
-binary_op = "||" | "&&" | rel_op | add_op | mul_op .
-rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
-add_op = "+" | "-" | "|" | "^" .
-mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
-
-unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
-
-
-uint.
-If the left operand of a non-constant shift expression is an untyped constant,
-it is first implicitly converted to the type it would assume if the shift expression were
-replaced by its left operand alone.
-
-var a [1024]byte
-var s uint = 33
-
-// The results of the following examples are given for 64-bit ints.
-var i = 1<<s // 1 has type int
-var j int32 = 1<<s // 1 has type int32; j == 0
-var k = uint64(1<<s) // 1 has type uint64; k == 1<<33
-var m int = 1.0<<s // 1.0 has type int; m == 1<<33
-var n = 1.0<<s == j // 1.0 has type int32; n == true
-var o = 1<<s == 2<<s // 1 and 2 have type int; o == false
-var p = 1<<s == 1<<33 // 1 has type int; p == true
-var u = 1.0<<s // illegal: 1.0 has type float64, cannot shift
-var u1 = 1.0<<s != 0 // illegal: 1.0 has type float64, cannot shift
-var u2 = 1<<s != 1.0 // illegal: 1 has type float64, cannot shift
-var v float32 = 1<<s // illegal: 1 has type float32, cannot shift
-var w int64 = 1.0<<33 // 1.0<<33 is a constant shift expression; w == 1<<33
-var x = a[1.0<<s] // panics: 1.0 has type int, but 1<<33 overflows array bounds
-var b = make([]byte, 1.0<<s) // 1.0 has type int; len(b) == 1<<33
-
-// The results of the following examples are given for 32-bit ints,
-// which means the shifts will overflow.
-var mm int = 1.0<<s // 1.0 has type int; mm == 0
-var oo = 1<<s == 2<<s // 1 and 2 have type int; oo == true
-var pp = 1<<s == 1<<33 // illegal: 1 has type int, but 1<<33 overflows int
-var xx = a[1.0<<s] // 1.0 has type int; xx == a[0]
-var bb = make([]byte, 1.0<<s) // 1.0 has type int; len(bb) == 0
-
-
-Operator precedence
-++ and -- operators form
-statements, not expressions, they fall
-outside the operator hierarchy.
-As a consequence, statement *p++ is the same as (*p)++.
-&& (logical AND),
-and finally || (logical OR):
-
-Precedence Operator
- 5 * / % << >> & &^
- 4 + - | ^
- 3 == != < <= > >=
- 2 &&
- 1 ||
-
-
-x / y * z is the same as (x / y) * z.
-
-+x
-23 + 3*x[i]
-x <= f()
-^a >> b
-f() || g()
-x == y+1 && <-chanInt > 0
-
-
-
-Arithmetic operators
-+,
--, *, /) apply to integer,
-floating-point, and complex types; + also applies to strings.
-The bitwise logical and shift operators apply to integers only.
-
-+ sum integers, floats, complex values, strings
-- difference integers, floats, complex values
-* product integers, floats, complex values
-/ quotient integers, floats, complex values
-% remainder integers
-
-& bitwise AND integers
-| bitwise OR integers
-^ bitwise XOR integers
-&^ bit clear (AND NOT) integers
-
-<< left shift integer << integer >= 0
->> right shift integer >> integer >= 0
-
-
-
-Integer operators
-
-x and y, the integer quotient
-q = x / y and remainder r = x % y satisfy the following
-relationships:
-
-x = q*y + r and |r| < |y|
-
-
-x / y truncated towards zero
-("truncated division").
-
- x y x / y x % y
- 5 3 1 2
--5 3 -1 -2
- 5 -3 -1 2
--5 -3 1 -2
-
-
-x is
-the most negative value for the int type of x, the quotient
-q = x / -1 is equal to x (and r = 0)
-due to two's-complement integer overflow:
-
- x, q
-int8 -128
-int16 -32768
-int32 -2147483648
-int64 -9223372036854775808
-
-
-
- x x / 4 x % 4 x >> 2 x & 3
- 11 2 3 2 3
--11 -2 -3 -3 1
-
-
-n times by 1 for a shift
-count of n.
-As a result, x << 1 is the same as x*2
-and x >> 1 is the same as
-x/2 but truncated towards negative infinity.
-+, -, and ^ are defined as
-follows:
-
-+x is 0 + x
--x negation is 0 - x
-^x bitwise complement is m ^ x with m = "all bits set to 1" for unsigned x
- and m = -1 for signed x
-
-
-
-Integer overflow
-
-+,
--, *, and << are
-computed modulo 2n, where n is the bit width of
-the unsigned integer's type.
-Loosely speaking, these unsigned integer operations
-discard high bits upon overflow, and programs may rely on "wrap around".
-+,
--, *, /, and << may legally
-overflow and the resulting value exists and is deterministically defined
-by the signed integer representation, the operation, and its operands.
-Overflow does not cause a run-time panic.
-A compiler may not optimize code under the assumption that overflow does
-not occur. For instance, it may not assume that x < x + 1 is always true.
-Floating-point operators
-
-+x is the same as x,
-while -x is the negation of x.
-The result of a floating-point or complex division by zero is not specified beyond the
-IEEE 754 standard; whether a run-time panic
-occurs is implementation-specific.
-x*y + z without rounding the intermediate result x*y.
-These examples show when a Go implementation can use that instruction:
-
-// FMA allowed for computing r, because x*y is not explicitly rounded:
-r = x*y + z
-r = z; r += x*y
-t = x*y; r = t + z
-*p = x*y; r = *p + z
-r = x*y + float64(z)
-
-// FMA disallowed for computing r, because it would omit rounding of x*y:
-r = float64(x*y) + z
-r = z; r += float64(x*y)
-t = float64(x*y); r = t + z
-
-
-String concatenation
-
-+ operator
-or the += assignment operator:
-
-s := "hi" + string(c)
-s += " and good bye"
-
-
-Comparison operators
-
-
-== equal
-!= not equal
-< less
-<= less or equal
-> greater
->= greater or equal
-
-
-== and != apply
-to operands that are comparable.
-The ordering operators <, <=, >, and >=
-apply to operands that are ordered.
-These terms and the result of the comparisons are defined as follows:
-
-
-
-true or both false.
- u and v are
- equal if both real(u) == real(v) and
- imag(u) == imag(v).
- nil.
- Pointers to distinct zero-size variables may or may not be equal.
- make
- or if both have value nil.
- nil.
- x of non-interface type X and
- a value t of interface type T are comparable when values
- of type X are comparable and
- X implements T.
- They are equal if t's dynamic type is identical to X
- and t's dynamic value is equal to x.
- nil.
-Comparison of pointer, channel, and interface values to nil
-is also allowed and follows from the general rules above.
-
-const c = 3 < 4 // c is the untyped boolean constant true
-
-type MyBool bool
-var x, y int
-var (
- // The result of a comparison is an untyped boolean.
- // The usual assignment rules apply.
- b3 = x == y // b3 has type bool
- b4 bool = x == y // b4 has type bool
- b5 MyBool = x == y // b5 has type MyBool
-)
-
-
-Logical operators
-
-
-&& conditional AND p && q is "if p then q else false"
-|| conditional OR p || q is "if p then true else q"
-! NOT !p is "not p"
-
-
-
-Address operators
-
-x of type T, the address operation
-&x generates a pointer of type *T to x.
-The operand must be addressable,
-that is, either a variable, pointer indirection, or slice indexing
-operation; or a field selector of an addressable struct operand;
-or an array indexing operation of an addressable array.
-As an exception to the addressability requirement, x may also be a
-(possibly parenthesized)
-composite literal.
-If the evaluation of x would cause a run-time panic,
-then the evaluation of &x does too.
-x of pointer type *T, the pointer
-indirection *x denotes the variable of type T pointed
-to by x.
-If x is nil, an attempt to evaluate *x
-will cause a run-time panic.
-
-&x
-&a[f(2)]
-&Point{2, 3}
-*p
-*pf(x)
-
-var x *int = nil
-*x // causes a run-time panic
-&*x // causes a run-time panic
-
-
-
-Receive operator
-
-ch of channel type,
-the value of the receive operation <-ch is the value received
-from the channel ch. The channel direction must permit receive operations,
-and the type of the receive operation is the element type of the channel.
-The expression blocks until a value is available.
-Receiving from a nil channel blocks forever.
-A receive operation on a closed channel can always proceed
-immediately, yielding the element type's zero value
-after any previously sent values have been received.
-
-v1 := <-ch
-v2 = <-ch
-f(<-ch)
-<-strobe // wait until clock pulse and discard received value
-
-
-
-x, ok = <-ch
-x, ok := <-ch
-var x, ok = <-ch
-var x, ok T = <-ch
-
-
-ok is true
-if the value received was delivered by a successful send operation to the
-channel, or false if it is a zero value generated because the
-channel is closed and empty.
-Conversions
-
-T(x)
-where T is a type and x is an expression
-that can be converted to type T.
-
-Conversion = Type "(" Expression [ "," ] ")" .
-
-
-* or <-,
-or if the type starts with the keyword func
-and has no result list, it must be parenthesized when
-necessary to avoid ambiguity:
-
-*Point(p) // same as *(Point(p))
-(*Point)(p) // p is converted to *Point
-<-chan int(c) // same as <-(chan int(c))
-(<-chan int)(c) // c is converted to <-chan int
-func()(x) // function signature func() x
-(func())(x) // x is converted to func()
-(func() int)(x) // x is converted to func() int
-func() int(x) // x is converted to func() int (unambiguous)
-
-
-x can be converted to
-type T if x is representable
-by a value of T.
-As a special case, an integer constant x can be explicitly converted to a
-string type using the
-same rule
-as for non-constant x.
-
-uint(iota) // iota value of type uint
-float32(2.718281828) // 2.718281828 of type float32
-complex128(1) // 1.0 + 0.0i of type complex128
-float32(0.49999999) // 0.5 of type float32
-float64(-1e-1000) // 0.0 of type float64
-string('x') // "x" of type string
-string(0x266c) // "♬" of type string
-MyString("foo" + "bar") // "foobar" of type MyString
-string([]byte{'a'}) // not a constant: []byte{'a'} is not a constant
-(*int)(nil) // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
-int(1.2) // illegal: 1.2 cannot be represented as an int
-string(65.0) // illegal: 65.0 is not an integer constant
-
-
-x can be converted to type T
-in any of these cases:
-
-
-
-x is assignable
- to T.
- x's type and T have identical
- underlying types.
- x's type and T are pointer types
- that are not defined types,
- and their pointer base types have identical underlying types.
- x's type and T are both integer or floating
- point types.
- x's type and T are both complex types.
- x is an integer or a slice of bytes or runes
- and T is a string type.
- x is a string and T is a slice of bytes or runes.
- x is a slice, T is a pointer to an array,
- and the slice and array types have identical element types.
-
-type Person struct {
- Name string
- Address *struct {
- Street string
- City string
- }
-}
-
-var data *struct {
- Name string `json:"name"`
- Address *struct {
- Street string `json:"street"`
- City string `json:"city"`
- } `json:"address"`
-}
-
-var person = (*Person)(data) // ignoring tags, the underlying types are identical
-
-
-x
-and incur a run-time cost.
-All other conversions only change the type but not the representation
-of x.
-unsafe
-implements this functionality under
-restricted circumstances.
-Conversions between numeric types
-
-
-
-
-v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0.
-The conversion always yields a valid value; there is no indication of overflow.
-x of type float32
-may be stored using additional precision beyond that of an IEEE 754 32-bit number,
-but float32(x) represents the result of rounding x's value to
-32-bit precision. Similarly, x + 0.1 may use more than 32 bits
-of precision, but float32(x + 0.1) does not.
-Conversions to and from a string type
-
-
-
-
-"\uFFFD".
-
-
-string('a') // "a"
-string(-1) // "\ufffd" == "\xef\xbf\xbd"
-string(0xf8) // "\u00f8" == "ø" == "\xc3\xb8"
-type MyString string
-MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5"
-
-
-string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
-string([]byte{}) // ""
-string([]byte(nil)) // ""
-
-type MyBytes []byte
-string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
-
-
-string([]rune{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
-string([]rune{}) // ""
-string([]rune(nil)) // ""
-
-type MyRunes []rune
-string(MyRunes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
-
-
-[]byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
-[]byte("") // []byte{}
-
-MyBytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
-
-
-[]rune(MyString("白鵬翔")) // []rune{0x767d, 0x9d6c, 0x7fd4}
-[]rune("") // []rune{}
-
-MyRunes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4}
-
-Conversions from slice to array pointer
-
-
-s := make([]byte, 2, 4)
-s0 := (*[0]byte)(s) // s0 != nil
-s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1]
-s2 := (*[2]byte)(s) // &s2[0] == &s[0]
-s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s)
-
-var t []string
-t0 := (*[0]string)(t) // t0 == nil
-t1 := (*[1]string)(t) // panics: len([1]string) > len(t)
-
-u := make([]byte, 0)
-u0 := (*[0]byte)(u) // u0 != nil
-
-
-Constant expressions
-
-
-const a = 2 + 3.0 // a == 5.0 (untyped floating-point constant)
-const b = 15 / 4 // b == 3 (untyped integer constant)
-const c = 15 / 4.0 // c == 3.75 (untyped floating-point constant)
-const Θ float64 = 3/2 // Θ == 1.0 (type float64, 3/2 is integer division)
-const Π float64 = 3/2. // Π == 1.5 (type float64, 3/2. is float division)
-const d = 1 << 3.0 // d == 8 (untyped integer constant)
-const e = 1.0 << 3 // e == 8 (untyped integer constant)
-const f = int32(1) << 33 // illegal (constant 8589934592 overflows int32)
-const g = float64(2) >> 1 // illegal (float64(2) is a typed floating-point constant)
-const h = "foo" > "bar" // h == true (untyped boolean constant)
-const j = true // j == true (untyped boolean constant)
-const k = 'w' + 1 // k == 'x' (untyped rune constant)
-const l = "hi" // l == "hi" (untyped string constant)
-const m = string(k) // m == "x" (type string)
-const Σ = 1 - 0.707i // (untyped complex constant)
-const Δ = Σ + 2.0e-4 // (untyped complex constant)
-const Φ = iota*1i - 1/1i // (untyped complex constant)
-
-
-complex to untyped
-integer, rune, or floating-point constants yields
-an untyped complex constant.
-
-const ic = complex(0, c) // ic == 3.75i (untyped complex constant)
-const iΘ = complex(0, Θ) // iΘ == 1i (type complex128)
-
-
-
-const Huge = 1 << 100 // Huge == 1267650600228229401496703205376 (untyped integer constant)
-const Four int8 = Huge >> 98 // Four == 4 (type int8)
-
-
-
-3.14 / 0.0 // illegal: division by zero
-
-
-
-uint(-1) // -1 cannot be represented as a uint
-int(3.14) // 3.14 cannot be represented as an int
-int64(Huge) // 1267650600228229401496703205376 cannot be represented as an int64
-Four * 300 // operand 300 cannot be represented as an int8 (type of Four)
-Four * 100 // product 400 cannot be represented as an int8 (type of Four)
-
-
-^ matches
-the rule for non-constants: the mask is all 1s for unsigned constants
-and -1 for signed and untyped constants.
-
-^1 // untyped integer constant, equal to -2
-uint8(^1) // illegal: same as uint8(-2), -2 cannot be represented as a uint8
-^uint8(1) // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE)
-int8(^1) // same as int8(-2)
-^int8(1) // same as -1 ^ int8(1) = -2
-
-
-Order of evaluation
-
-
-y[f()], ok = g(h(), i()+x[j()], <-c), k()
-
-f(), h(), i(), j(),
-<-c, g(), and k().
-However, the order of those events compared to the evaluation
-and indexing of x and the evaluation
-of y is not specified.
-
-a := 1
-f := func() int { a++; return a }
-x := []int{a, f()} // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
-m := map[int]int{a: 1, a: 2} // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
-n := map[int]int{a: f()} // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
-
-
-
-var a, b, c = f() + v(), g(), sqr(u()) + v()
-
-func f() int { return c }
-func g() int { return a }
-func sqr(x int) int { return x*x }
-
-// functions u and v are independent of all other variables and functions
-
-
-u(), sqr(), v(),
-f(), v(), and g().
-x + (y + z) the addition y + z
-is performed before adding x.
-Statements
-
-
-Statement =
- Declaration | LabeledStmt | SimpleStmt |
- GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
- FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
- DeferStmt .
-
-SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
-
-
-Terminating statements
-
-
-
-
-
-panic.
-
-
-
-
-
-
-
-
-
-
-
-Empty statements
-
-
-EmptyStmt = .
-
-
-
-Labeled statements
-
-goto,
-break or continue statement.
-
-LabeledStmt = Label ":" Statement .
-Label = identifier .
-
-
-
-Error: log.Panic("error encountered")
-
-
-
-Expression statements
-
-
-ExpressionStmt = Expression .
-
-
-
-append cap complex imag len make new real
-unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
-
-
-
-h(x+y)
-f.Close()
-<-ch
-(<-ch)
-len("foo") // illegal if len is the built-in function
-
-
-
-Send statements
-
-
-SendStmt = Channel "<-" Expression .
-Channel = Expression .
-
-
-nil channel blocks forever.
-
-ch <- 3 // send value 3 to channel ch
-
-
-
-IncDec statements
-
-1.
-As with an assignment, the operand must be addressable
-or a map index expression.
-
-IncDecStmt = Expression ( "++" | "--" ) .
-
-
-
-IncDec statement Assignment
-x++ x += 1
-x-- x -= 1
-
-
-
-Assignments
-
-
-Assignment = ExpressionList assign_op ExpressionList .
-
-assign_op = [ add_op | mul_op ] "=" .
-
-
-= assignments only) the
-blank identifier.
-Operands may be parenthesized.
-
-x = 1
-*p = f()
-a[i] = 23
-(k) = <-ch // same as: k = <-ch
-
-
-x op=
-y where op is a binary arithmetic operator
-is equivalent to x = x op
-(y) but evaluates x
-only once. The op= construct is a single token.
-In assignment operations, both the left- and right-hand expression lists
-must contain exactly one single-valued expression, and the left-hand
-expression must not be the blank identifier.
-
-a[i] <<= 2
-i &^= 1<<n
-
-
-f is a function returning two values,
-
-x, y = f()
-
-
-x and the second to y.
-In the second form, the number of operands on the left must equal the number
-of expressions on the right, each of which must be single-valued, and the
-nth expression on the right is assigned to the nth
-operand on the left:
-
-one, two, three = '一', '二', '三'
-
-
-
-_ = x // evaluate x but ignore it
-x, _ = f() // evaluate f() but ignore second result value
-
-
-
-a, b = b, a // exchange a and b
-
-x := []int{1, 2, 3}
-i := 0
-i, x[i] = 1, 2 // set i = 1, x[0] = 2
-
-i = 0
-x[i], i = 2, 1 // set x[0] = 2, i = 1
-
-x[0], x[0] = 1, 2 // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)
-
-x[1], x[3] = 4, 5 // set x[1] = 4, then panic setting x[3] = 5.
-
-type Point struct { x, y int }
-var p *Point
-x[2], p.x = 6, 7 // set x[2] = 6, then panic setting p.x = 7
-
-i = 2
-x = []int{3, 5, 7}
-for i, x[i] = range x { // set i, x[2] = 0, x[0]
- break
-}
-// after this loop, i == 0 and x == []int{3, 5, 3}
-
-
-
-
-
-bool.
-If statements
-
-
-IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
-
-
-
-if x > max {
- x = max
-}
-
-
-
-if x := f(); x < y {
- return x
-} else if x > z {
- return z
-} else {
- return y
-}
-
-
-
-Switch statements
-
-
-SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
-
-
-Expression switches
-
-true.
-
-ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
-ExprCaseClause = ExprSwitchCase ":" StatementList .
-ExprSwitchCase = "case" ExpressionList | "default" .
-
-
-nil cannot be used as a switch expression.
-The switch expression type must be comparable.
-x and the value t
-of the switch expression, x == t must be a valid comparison.
-t without explicit type; it is that
-value of t against which each case expression x is tested
-for equality.
-
-switch tag {
-default: s3()
-case 0, 1, 2, 3: s1()
-case 4, 5, 6, 7: s2()
-}
-
-switch x := f(); { // missing switch expression means "true"
-case x < 0: return -x
-default: return x
-}
-
-switch {
-case x < y: f1()
-case x < z: f2()
-case x == 4: f3()
-}
-
-
-Type switches
-
-type rather than an actual type:
-
-switch x.(type) {
-// cases
-}
-
-
-T against the dynamic type of the
-expression x. As with type assertions, x must be of
-interface type, and each non-interface type
-T listed in a case must implement the type of x.
-The types listed in the cases of a type switch must all be
-different.
-
-TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
-TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
-TypeCaseClause = TypeSwitchCase ":" StatementList .
-TypeSwitchCase = "case" TypeList | "default" .
-TypeList = Type { "," Type } .
-
-
-nil;
-that case is selected when the expression in the TypeSwitchGuard
-is a nil interface value.
-There may be at most one nil case.
-x of type interface{},
-the following type switch:
-
-switch i := x.(type) {
-case nil:
- printString("x is nil") // type of i is type of x (interface{})
-case int:
- printInt(i) // type of i is int
-case float64:
- printFloat64(i) // type of i is float64
-case func(int) float64:
- printFunction(i) // type of i is func(int) float64
-case bool, string:
- printString("type is bool or string") // type of i is type of x (interface{})
-default:
- printString("don't know the type") // type of i is type of x (interface{})
-}
-
-
-
-v := x // x is evaluated exactly once
-if v == nil {
- i := v // type of i is type of x (interface{})
- printString("x is nil")
-} else if i, isInt := v.(int); isInt {
- printInt(i) // type of i is int
-} else if i, isFloat64 := v.(float64); isFloat64 {
- printFloat64(i) // type of i is float64
-} else if i, isFunc := v.(func(int) float64); isFunc {
- printFunction(i) // type of i is func(int) float64
-} else {
- _, isBool := v.(bool)
- _, isString := v.(string)
- if isBool || isString {
- i := v // type of i is type of x (interface{})
- printString("type is bool or string")
- } else {
- i := v // type of i is type of x (interface{})
- printString("don't know the type")
- }
-}
-
-
-For statements
-
-
-ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
-Condition = Expression .
-
-
-For statements with single condition
-
-true.
-
-for a < b {
- a *= 2
-}
-
-
-For statements with
-
-for clause
-ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
-InitStmt = SimpleStmt .
-PostStmt = SimpleStmt .
-
-
-
-for i := 0; i < 10; i++ {
- f(i)
-}
-
-
-true.
-
-for cond { S() } is the same as for ; cond ; { S() }
-for { S() } is the same as for true { S() }
-
-
-For statements with
-
-range clause
-RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
-
-
-x is evaluated once before beginning the loop,
-with one exception: if at most one iteration variable is present and
-len(x) is constant,
-the range expression is not evaluated.
-
-Range expression 1st value 2nd value
-
-array or slice a [n]E, *[n]E, or []E index i int a[i] E
-string s string type index i int see below rune
-map m map[K]V key k K m[k] V
-channel c chan E, <-chan E element e E
-
-
-
-
-
-a, the index iteration
-values are produced in increasing order, starting at element index 0.
-If at most one iteration variable is present, the range loop produces
-iteration values from 0 up to len(a)-1 and does not index into the array
-or slice itself. For a nil slice, the number of iterations is 0.
-rune, will be the value of
-the corresponding code point. If the iteration encounters an invalid
-UTF-8 sequence, the second value will be 0xFFFD,
-the Unicode replacement character, and the next iteration will advance
-a single byte in the string.
-nil, the number of iterations is 0.
-nil, the range expression blocks forever.
-:=).
-In this case their types are set to the types of the respective iteration values
-and their scope is the block of the "for"
-statement; they are re-used in each iteration.
-If the iteration variables are declared outside the "for" statement,
-after execution their values will be those of the last iteration.
-
-var testdata *struct {
- a *[7]int
-}
-for i, _ := range testdata.a {
- // testdata.a is never evaluated; len(testdata.a) is constant
- // i ranges from 0 to 6
- f(i)
-}
-
-var a [10]string
-for i, s := range a {
- // type of i is int
- // type of s is string
- // s == a[i]
- g(i, s)
-}
-
-var key string
-var val interface{} // element type of m is assignable to val
-m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
-for key, val = range m {
- h(key, val)
-}
-// key == last map key encountered in iteration
-// val == map[key]
-
-var ch chan Work = producer()
-for w := range ch {
- doWork(w)
-}
-
-// empty a channel
-for range ch {}
-
-
-
-Go statements
-
-
-GoStmt = "go" Expression .
-
-
-
-go Server()
-go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c)
-
-
-
-Select statements
-
-
-SelectStmt = "select" "{" { CommClause } "}" .
-CommClause = CommCase ":" StatementList .
-CommCase = "case" ( SendStmt | RecvStmt ) | "default" .
-RecvStmt = [ ExpressionList "=" | IdentifierList ":=" ] RecvExpr .
-RecvExpr = Expression .
-
-
-
-
-
-nil channels can never proceed,
-a select with only nil channels and no default case blocks forever.
-
-var a []int
-var c, c1, c2, c3, c4 chan int
-var i1, i2 int
-select {
-case i1 = <-c1:
- print("received ", i1, " from c1\n")
-case c2 <- i2:
- print("sent ", i2, " to c2\n")
-case i3, ok := (<-c3): // same as: i3, ok := <-c3
- if ok {
- print("received ", i3, " from c3\n")
- } else {
- print("c3 is closed\n")
- }
-case a[f()] = <-c4:
- // same as:
- // case t := <-c4
- // a[f()] = t
-default:
- print("no communication\n")
-}
-
-for { // send random sequence of bits to c
- select {
- case c <- 0: // note: no statement, no fallthrough, no folding of cases
- case c <- 1:
- }
-}
-
-select {} // block forever
-
-
-
-Return statements
-
-F terminates the execution
-of F, and optionally provides one or more result values.
-Any functions deferred by F
-are executed before F returns to its caller.
-
-ReturnStmt = "return" [ ExpressionList ] .
-
-
-
-func noResult() {
- return
-}
-
-
-
-
-
-
-func simpleF() int {
- return 2
-}
-
-func complexF1() (re float64, im float64) {
- return -7.0, -4.0
-}
-
-
-func complexF2() (re float64, im float64) {
- return complexF1()
-}
-
-
-func complexF3() (re float64, im float64) {
- re = 7.0
- im = 4.0
- return
-}
-
-func (devnull) Write(p []byte) (n int, _ error) {
- n = len(p)
- return
-}
-
-
-func f(n int) (res int, err error) {
- if _, err := f(n-1); err != nil {
- return // invalid return statement: err is shadowed
- }
- return
-}
-
-
-Break statements
-
-
-BreakStmt = "break" [ Label ] .
-
-
-
-OuterLoop:
- for i = 0; i < n; i++ {
- for j = 0; j < m; j++ {
- switch a[i][j] {
- case nil:
- state = Error
- break OuterLoop
- case item:
- state = Found
- break OuterLoop
- }
- }
- }
-
-
-Continue statements
-
-
-ContinueStmt = "continue" [ Label ] .
-
-
-
-RowLoop:
- for y, row := range rows {
- for x, data := range row {
- if data == endOfRow {
- continue RowLoop
- }
- row[x] = data + bias(x, y)
- }
- }
-
-
-Goto statements
-
-
-GotoStmt = "goto" Label .
-
-
-
-goto Error
-
-
-
- goto L // BAD
- v := 3
-L:
-
-
-L skips
-the creation of v.
-
-if n%2 == 1 {
- goto L1
-}
-for n > 0 {
- f()
- n--
-L1:
- f()
- n--
-}
-
-
-L1 is inside
-the "for" statement's block but the goto is not.
-Fallthrough statements
-
-
-FallthroughStmt = "fallthrough" .
-
-
-
-Defer statements
-
-
-DeferStmt = "defer" Expression .
-
-
-nil, execution panics
-when the function is invoked, not when the "defer" statement is executed.
-
-lock(l)
-defer unlock(l) // unlocking happens before surrounding function returns
-
-// prints 3 2 1 0 before surrounding function returns
-for i := 0; i <= 3; i++ {
- defer fmt.Print(i)
-}
-
-// f returns 42
-func f() (result int) {
- defer func() {
- // result is accessed after it was set to 6 by the return statement
- result *= 7
- }()
- return 6
-}
-
-
-Built-in functions
-
-Close
-
-c, the built-in function close(c)
-records that no more values will be sent on the channel.
-It is an error if c is a receive-only channel.
-Sending to or closing a closed channel causes a run-time panic.
-Closing the nil channel also causes a run-time panic.
-After calling close, and after any previously
-sent values have been received, receive operations will return
-the zero value for the channel's type without blocking.
-The multi-valued receive operation
-returns a received value along with an indication of whether the channel is closed.
-Length and capacity
-
-len and cap take arguments
-of various types and return a result of type int.
-The implementation guarantees that the result always fits into an int.
-
-Call Argument type Result
-
-len(s) string type string length in bytes
- [n]T, *[n]T array length (== n)
- []T slice length
- map[K]T map length (number of defined keys)
- chan T number of elements queued in channel buffer
-
-cap(s) [n]T, *[n]T array length (== n)
- []T slice capacity
- chan T channel buffer capacity
-
-
-
-0 <= len(s) <= cap(s)
-
-
-nil slice, map or channel is 0.
-The capacity of a nil slice or channel is 0.
-len(s) is constant if
-s is a string constant. The expressions len(s) and
-cap(s) are constants if the type of s is an array
-or pointer to an array and the expression s does not contain
-channel receives or (non-constant)
-function calls; in this case s is not evaluated.
-Otherwise, invocations of len and cap are not
-constant and s is evaluated.
-
-const (
- c1 = imag(2i) // imag(2i) = 2.0 is a constant
- c2 = len([10]float64{2}) // [10]float64{2} contains no function calls
- c3 = len([10]float64{c1}) // [10]float64{c1} contains no function calls
- c4 = len([10]float64{imag(2i)}) // imag(2i) is a constant and no function call is issued
- c5 = len([10]float64{imag(z)}) // invalid: imag(z) is a (non-constant) function call
-)
-var z complex128
-
-
-Allocation
-
-new takes a type T,
-allocates storage for a variable of that type
-at run time, and returns a value of type *T
-pointing to it.
-The variable is initialized as described in the section on
-initial values.
-
-new(T)
-
-
-
-type S struct { a int; b float64 }
-new(S)
-
-
-S,
-initializes it (a=0, b=0.0),
-and returns a value of type *S containing the address
-of the location.
-Making slices, maps and channels
-
-make takes a type T,
-which must be a slice, map or channel type,
-optionally followed by a type-specific list of expressions.
-It returns a value of type T (not *T).
-The memory is initialized as described in the section on
-initial values.
-
-Call Type T Result
-
-make(T, n) slice slice of type T with length n and capacity n
-make(T, n, m) slice slice of type T with length n and capacity m
-
-make(T) map map of type T
-make(T, n) map map of type T with initial space for approximately n elements
-
-make(T) channel unbuffered channel of type T
-make(T, n) channel buffered channel of type T, buffer size n
-
-
-
-n and m must be of integer type
-or an untyped constant.
-A constant size argument must be non-negative and representable
-by a value of type int; if it is an untyped constant it is given type int.
-If both n and m are provided and are constant, then
-n must be no larger than m.
-If n is negative or larger than m at run time,
-a run-time panic occurs.
-
-s := make([]int, 10, 100) // slice with len(s) == 10, cap(s) == 100
-s := make([]int, 1e3) // slice with len(s) == cap(s) == 1000
-s := make([]int, 1<<63) // illegal: len(s) is not representable by a value of type int
-s := make([]int, 10, 0) // illegal: len(s) > cap(s)
-c := make(chan int, 10) // channel with a buffer size of 10
-m := make(map[string]int, 100) // map with initial space for approximately 100 elements
-
-
-make with a map type and size hint n will
-create a map with initial space to hold n map elements.
-The precise behavior is implementation-dependent.
-Appending to and copying slices
-
-append and copy assist in
-common slice operations.
-For both functions, the result is independent of whether the memory referenced
-by the arguments overlaps.
-append
-appends zero or more values x
-to s of type S, which must be a slice type, and
-returns the resulting slice, also of type S.
-The values x are passed to a parameter of type ...T
-where T is the element type of
-S and the respective
-parameter passing rules apply.
-As a special case, append also accepts a first argument
-assignable to type []byte with a second argument of
-string type followed by .... This form appends the
-bytes of the string.
-
-append(s S, x ...T) S // T is the element type of S
-
-
-s is not large enough to fit the additional
-values, append allocates a new, sufficiently large underlying
-array that fits both the existing slice elements and the additional values.
-Otherwise, append re-uses the underlying array.
-
-s0 := []int{0, 0}
-s1 := append(s0, 2) // append a single element s1 == []int{0, 0, 2}
-s2 := append(s1, 3, 5, 7) // append multiple elements s2 == []int{0, 0, 2, 3, 5, 7}
-s3 := append(s2, s0...) // append a slice s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
-s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
-
-var t []interface{}
-t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"}
-
-var b []byte
-b = append(b, "bar"...) // append string contents b == []byte{'b', 'a', 'r' }
-
-
-copy copies slice elements from
-a source src to a destination dst and returns the
-number of elements copied.
-Both arguments must have identical element type T and must be
-assignable to a slice of type []T.
-The number of elements copied is the minimum of
-len(src) and len(dst).
-As a special case, copy also accepts a destination argument assignable
-to type []byte with a source argument of a string type.
-This form copies the bytes from the string into the byte slice.
-
-copy(dst, src []T) int
-copy(dst []byte, src string) int
-
-
-
-var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
-var s = make([]int, 6)
-var b = make([]byte, 5)
-n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
-n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
-n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello")
-
-
-
-Deletion of map elements
-
-delete removes the element with key
-k from a map m. The
-type of k must be assignable
-to the key type of m.
-
-delete(m, k) // remove element m[k] from map m
-
-
-m is nil or the element m[k]
-does not exist, delete is a no-op.
-Manipulating complex numbers
-
-complex constructs a complex
-value from a floating-point real and imaginary part, while
-real and imag
-extract the real and imaginary parts of a complex value.
-
-complex(realPart, imaginaryPart floatT) complexT
-real(complexT) floatT
-imag(complexT) floatT
-
-
-complex, the two arguments must be of the same
-floating-point type and the return type is the complex type
-with the corresponding floating-point constituents:
-complex64 for float32 arguments, and
-complex128 for float64 arguments.
-If one of the arguments evaluates to an untyped constant, it is first implicitly
-converted to the type of the other argument.
-If both arguments evaluate to untyped constants, they must be non-complex
-numbers or their imaginary parts must be zero, and the return value of
-the function is an untyped complex constant.
-real and imag, the argument must be
-of complex type, and the return type is the corresponding floating-point
-type: float32 for a complex64 argument, and
-float64 for a complex128 argument.
-If the argument evaluates to an untyped constant, it must be a number,
-and the return value of the function is an untyped floating-point constant.
-real and imag functions together form the inverse of
-complex, so for a value z of a complex type Z,
-z == Z(complex(real(z), imag(z))).
-
-var a = complex(2, -2) // complex128
-const b = complex(1.0, -1.4) // untyped complex constant 1 - 1.4i
-x := float32(math.Cos(math.Pi/2)) // float32
-var c64 = complex(5, -x) // complex64
-var s int = complex(1, 0) // untyped complex constant 1 + 0i can be converted to int
-_ = complex(1, 2<<s) // illegal: 2 assumes floating-point type, cannot shift
-var rl = real(c64) // float32
-var im = imag(a) // float64
-const c = imag(b) // untyped constant -1.4
-_ = imag(3 << s) // illegal: 3 assumes complex type, cannot shift
-
-
-Handling panics
-
-panic and recover,
-assist in reporting and handling run-time panics
-and program-defined error conditions.
-
-func panic(interface{})
-func recover() interface{}
-
-
-F,
-an explicit call to panic or a run-time panic
-terminates the execution of F.
-Any functions deferred by F
-are then executed as usual.
-Next, any deferred functions run by F's caller are run,
-and so on up to any deferred by the top-level function in the executing goroutine.
-At that point, the program is terminated and the error
-condition is reported, including the value of the argument to panic.
-This termination sequence is called panicking.
-
-panic(42)
-panic("unreachable")
-panic(Error("cannot parse"))
-
-
-recover function allows a program to manage behavior
-of a panicking goroutine.
-Suppose a function G defers a function D that calls
-recover and a panic occurs in a function on the same goroutine in which G
-is executing.
-When the running of deferred functions reaches D,
-the return value of D's call to recover will be the value passed to the call of panic.
-If D returns normally, without starting a new
-panic, the panicking sequence stops. In that case,
-the state of functions called between G and the call to panic
-is discarded, and normal execution resumes.
-Any functions deferred by G before D are then run and G's
-execution terminates by returning to its caller.
-recover is nil if any of the following conditions holds:
-
-
-
-panic's argument was nil;
-recover was not called directly by a deferred function.
-protect function in the example below invokes
-the function argument g and protects callers from
-run-time panics raised by g.
-
-func protect(g func()) {
- defer func() {
- log.Println("done") // Println executes normally even if there is a panic
- if x := recover(); x != nil {
- log.Printf("run time panic: %v", x)
- }
- }()
- log.Println("start")
- g()
-}
-
-
-
-Bootstrapping
-
-
-Function Behavior
-
-print prints all arguments; formatting of arguments is implementation-specific
-println like print but prints spaces between arguments and a newline at the end
-
-
-print and println need not
-accept arbitrary argument types, but printing of boolean, numeric, and string
-types must be supported.
-Packages
-
-Source file organization
-
-
-SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
-
-
-Package clause
-
-
-PackageClause = "package" PackageName .
-PackageName = identifier .
-
-
-
-package math
-
-
-Import declarations
-
-
-ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
-ImportSpec = [ "." | PackageName ] ImportPath .
-ImportPath = string_lit .
-
-
-.) appears instead of a name, all the
-package's exported identifiers declared in that package's
-package block will be declared in the importing source
-file's file block and must be accessed without a qualifier.
-!"#$%&'()*,:;<=>?[\]^`{|}
-and the Unicode replacement character U+FFFD.
-package math, which exports function Sin, and
-installed the compiled package in the file identified by
-"lib/math".
-This table illustrates how Sin is accessed in files
-that import the package after the
-various types of import declaration.
-
-Import declaration Local name of Sin
-
-import "lib/math" math.Sin
-import m "lib/math" m.Sin
-import . "lib/math" Sin
-
-
-
-import _ "lib/math"
-
-
-
-An example package
-
-
-package main
-
-import "fmt"
-
-// Send the sequence 2, 3, 4, … to channel 'ch'.
-func generate(ch chan<- int) {
- for i := 2; ; i++ {
- ch <- i // Send 'i' to channel 'ch'.
- }
-}
-
-// Copy the values from channel 'src' to channel 'dst',
-// removing those divisible by 'prime'.
-func filter(src <-chan int, dst chan<- int, prime int) {
- for i := range src { // Loop over values received from 'src'.
- if i%prime != 0 {
- dst <- i // Send 'i' to channel 'dst'.
- }
- }
-}
-
-// The prime sieve: Daisy-chain filter processes together.
-func sieve() {
- ch := make(chan int) // Create a new channel.
- go generate(ch) // Start generate() as a subprocess.
- for {
- prime := <-ch
- fmt.Print(prime, "\n")
- ch1 := make(chan int)
- go filter(ch, ch1, prime)
- ch = ch1
- }
-}
-
-func main() {
- sieve()
-}
-
-
-Program initialization and execution
-
-The zero value
-new, or when
-a new value is created, either through a composite literal or a call
-of make,
-and no explicit initialization is provided, the variable or value is
-given a default value. Each element of such a variable or value is
-set to the zero value for its type: false for booleans,
-0 for numeric types, ""
-for strings, and nil for pointers, functions, interfaces, slices, channels, and maps.
-This initialization is done recursively, so for instance each element of an
-array of structs will have its fields zeroed if no value is specified.
-
-var i int
-var i int = 0
-
-
-
-type T struct { i int; f float64; next *T }
-t := new(T)
-
-
-
-t.i == 0
-t.f == 0.0
-t.next == nil
-
-
-
-var t T
-
-
-Package initialization
-
-
-var x = a
-var a, b = f() // a and b are initialized together, before x is initialized
-
-
-x's
-initialization expression refers to a function whose body refers to
-variable y then x depends on y.
-Specifically:
-
-
-
-m is a
-method value or
-method expression of the form
-t.m, where the (static) type of t is
-not an interface type, and the method m is in the
-method set of t.
-It is immaterial whether the resulting function value
-t.m is invoked.
-x depends on a variable
-y if x's initialization expression or body
-(for functions and methods) contains a reference to y
-or to a function or method that depends on y.
-
-var (
- a = c + b // == 9
- b = f() // == 4
- c = f() // == 5
- d = 3 // == 5 after initialization has finished
-)
-
-func f() int {
- d++
- return d
-}
-
-
-d, b, c, a.
-Note that the order of subexpressions in initialization expressions is irrelevant:
-a = c + b and a = b + c result in the same initialization
-order in this example.
-
-var x = I(T{}).ab() // x has an undetected, hidden dependency on a and b
-var _ = sideEffect() // unrelated to x, a, or b
-var a = b
-var b = 42
-
-type I interface { ab() []int }
-type T struct{}
-func (T) ab() []int { return []int{a, b} }
-
-
-a will be initialized after b but
-whether x is initialized before b, between
-b and a, or after a, and
-thus also the moment at which sideEffect() is called (before
-or after x is initialized) is not specified.
-init
-declared in the package block, with no arguments and no result parameters.
-
-func init() { … }
-
-
-init identifier can
-be used only to declare init functions, yet the identifier
-itself is not declared. Thus
-init functions cannot be referred to from anywhere
-in a program.
-init
-functions in the order they appear in the source, possibly in multiple files,
-as presented to the compiler.
-If a package has imports, the imported packages are initialized
-before initializing the package itself. If multiple packages import
-a package, the imported package will be initialized only once.
-The importing of packages, by construction, guarantees that there
-can be no cyclic initialization dependencies.
-init functions—happens in a single goroutine,
-sequentially, one package at a time.
-An init function may launch other goroutines, which can run
-concurrently with the initialization code. However, initialization
-always sequences
-the init functions: it will not invoke the next one
-until the previous one has returned.
-Program execution
-main and
-declare a function main that takes no
-arguments and returns no value.
-
-func main() { … }
-
-
-main.
-When that function invocation returns, the program exits.
-It does not wait for other (non-main) goroutines to complete.
-Errors
-
-error is defined as
-
-type error interface {
- Error() string
-}
-
-
-
-func Read(f *File, b []byte) (n int, err error)
-
-
-Run-time panics
-
-panic
-with a value of the implementation-defined interface type runtime.Error.
-That type satisfies the predeclared interface type
-error.
-The exact error values that
-represent distinct run-time error conditions are unspecified.
-
-package runtime
-
-type Error interface {
- error
- // and perhaps other methods
-}
-
-
-System considerations
-
-Package
-
-unsafeunsafe, known to the compiler
-and accessible through the import path "unsafe",
-provides facilities for low-level programming including operations
-that violate the type system. A package using unsafe
-must be vetted manually for type safety and may not be portable.
-The package provides the following interface:
-
-package unsafe
-
-type ArbitraryType int // shorthand for an arbitrary Go type; it is not a real type
-type Pointer *ArbitraryType
-
-func Alignof(variable ArbitraryType) uintptr
-func Offsetof(selector ArbitraryType) uintptr
-func Sizeof(variable ArbitraryType) uintptr
-
-type IntegerType int // shorthand for an integer type; it is not a real type
-func Add(ptr Pointer, len IntegerType) Pointer
-func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
-
-
-Pointer is a pointer type but a Pointer
-value may not be dereferenced.
-Any pointer or value of underlying type uintptr can be converted to
-a type of underlying type Pointer and vice versa.
-The effect of converting between Pointer and uintptr is implementation-defined.
-
-var f float64
-bits = *(*uint64)(unsafe.Pointer(&f))
-
-type ptr unsafe.Pointer
-bits = *(*uint64)(ptr(&f))
-
-var p ptr = nil
-
-
-Alignof and Sizeof take an expression x
-of any type and return the alignment or size, respectively, of a hypothetical variable v
-as if v was declared via var v = x.
-Offsetof takes a (possibly parenthesized) selector
-s.f, denoting a field f of the struct denoted by s
-or *s, and returns the field offset in bytes relative to the struct's address.
-If f is an embedded field, it must be reachable
-without pointer indirections through fields of the struct.
-For a struct s with field f:
-
-uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
-
-
-Alignof
-takes an expression denoting a variable of any type and returns the
-alignment of the (type of the) variable in bytes. For a variable
-x:
-
-uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0
-
-
-Alignof, Offsetof, and
-Sizeof are compile-time constant expressions of type uintptr.
-Add adds len to ptr
-and returns the updated pointer unsafe.Pointer(uintptr(ptr) + uintptr(len)).
-The len argument must be of integer type or an untyped constant.
-A constant len argument must be representable by a value of type int;
-if it is an untyped constant it is given type int.
-The rules for valid uses of Pointer still apply.
-Slice returns a slice whose underlying array starts at ptr
-and whose length and capacity are len.
-Slice(ptr, len) is equivalent to
-
-(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
-
-
-ptr
-is nil and len is zero,
-Slice returns nil.
-len argument must be of integer type or an untyped constant.
-A constant len argument must be non-negative and representable by a value of type int;
-if it is an untyped constant it is given type int.
-At run time, if len is negative,
-or if ptr is nil and len is not zero,
-a run-time panic occurs.
-Size and alignment guarantees
-
-
-type size in bytes
-
-byte, uint8, int8 1
-uint16, int16 2
-uint32, int32, float32 4
-uint64, int64, float64, complex64 8
-complex128 16
-
-
-
-
-
-x of any type: unsafe.Alignof(x) is at least 1.
-x of struct type: unsafe.Alignof(x) is the largest of
- all the values unsafe.Alignof(x.f) for each field f of x, but at least 1.
-x of array type: unsafe.Alignof(x) is the same as
- the alignment of a variable of the array's element type.
-
-The kth receive on a channel with capacity C is synchronized before the completion of the k+Cth send from that channel completes. +The kth receive from a channel with capacity C is synchronized before the completion of the k+Cth send on that channel.
diff --git a/doc/go_spec.html b/doc/go_spec.html index db5fba45..183bc7fb 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -8,8 +8,6 @@
This is the reference manual for the Go programming language. -The pre-Go1.18 version, without generics, can be found -here. For more information and other documents, see go.dev.
@@ -1858,110 +1856,10 @@ The underlying type of[]B1, B3, and B4 i
The underlying type of P is interface{}.
-
-Each non-interface type T has a core type, which is the same as the
-underlying type of T.
-
-An interface T has a core type if one of the following
-conditions is satisfied:
-
U which is the underlying type
-of all types in the type set of T; or
-T contains only channel types
-with identical element type E, and all directional channels have the same
-direction.
--No other interfaces have a core type. -
- --The core type of an interface is, depending on the condition that is satisfied, either: -
- -U; or
-chan E if T contains only bidirectional
-channels, or the type chan<- E or <-chan E
-depending on the direction of the directional channels present.
--By definition, a core type is never a defined type, -type parameter, or -interface type. -
- --Examples of interfaces with core types: -
- -
-type Celsius float32
-type Kelvin float32
-
-interface{ int } // int
-interface{ Celsius|Kelvin } // float32
-interface{ ~chan int } // chan int
-interface{ ~chan int|~chan<- int } // chan<- int
-interface{ ~[]*data; String() string } // []*data
-
-
--Examples of interfaces without core types: -
- -
-interface{} // no single underlying type
-interface{ Celsius|float64 } // no single underlying type
-interface{ chan int | chan<- string } // channels have different element types
-interface{ <-chan int | chan<- int } // directional channels have different directions
-
-
-
-Some operations (slice expressions,
-append and copy)
-rely on a slightly more loose form of core types which accept byte slices and strings.
-Specifically, if there are exactly two types, []byte and string,
-which are the underlying types of all types in the type set of interface T,
-the core type of T is called bytestring.
-
-Examples of interfaces with bytestring core types:
-
-interface{ int } // int (same as ordinary core type)
-interface{ []byte | string } // bytestring
-interface{ ~[]byte | myString } // bytestring
-
-
-
-Note that bytestring is not a real type; it cannot be used to declare
-variables or compose other types. It exists solely to describe the behavior of some
-operations that read from a sequence of bytes, which may be a byte slice or a string.
-
-Two types are either identical or different. +Two types are either identical ("the same") or different.
@@ -3255,7 +3153,8 @@ math.Sin // denotes the Sin function in package math
-Composite literals construct new composite values each time they are evaluated. +Composite literals construct new values for structs, arrays, slices, and maps +each time they are evaluated. They consist of the type of the literal followed by a brace-bound list of elements. Each element may optionally be preceded by a corresponding key.
@@ -3273,10 +3172,14 @@ Element = Expression | LiteralValue .
-The LiteralType's core type T
+Unless the LiteralType is a type parameter,
+its underlying type
must be a struct, array, slice, or map type
(the syntax enforces this constraint except when the type is given
as a TypeName).
+If the LiteralType is a type parameter, all types in its type set
+must have the same underlying type which must be
+a valid composite literal type.
The types of the elements and keys must be assignable
to the respective field, element, and key types of type T;
there is no additional conversion.
@@ -3461,7 +3364,6 @@ noteFrequency := map[string]float32{
}
-
@@ -3934,11 +3836,12 @@ The following rules apply:
-If a is neither a map nor a type parameter:
+If a is neither a map nor a type parameter:
x must be an untyped constant or its
- core type must be an integerx must be an untyped constant, or its type must be
+ an integer or a type parameter whose type set
+ contains only integer typesintintnil map causes a
Slice expressions construct a substring or slice from a string, array, pointer -to array, or slice. There are two variants: a simple form that specifies a low +to array, or slice operand. +There are two variants: a simple form that specifies a low and high bound, and a full form that also specifies a bound on the capacity.
+
+If the operand type is a type parameter,
+unless its type set contains string types,
+all types in the type set must have the same underlying type, and the slice expression
+must be valid for an operand of that type.
+If the type set contains string types it may also contain byte slices with underlying
+type []byte.
+In this case, the slice expression must be valid for an operand of string
+type.
+
-The primary expression
+For a string, array, pointer to array, or slice a, the primary expression
@@ -4067,9 +3982,7 @@ a[low : high]
-constructs a substring or slice. The core type of
-a must be a string, array, pointer to array, slice, or a
-bytestring.
+constructs a substring or slice.
The indices low and
high select which elements of operand a appear
in the result. The result has indices starting at 0 and length equal to
@@ -4149,7 +4062,7 @@ s3 := s[:0] // s3 == nil
-The primary expression
+For an array, pointer to array, or slice a (but not a string), the primary expression
@@ -4160,8 +4073,6 @@ a[low : high : max] constructs a slice of the same type, and with the same length and elements as the simple slice expressiona[low : high]. Additionally, it controls the resulting slice's capacity by setting it tomax - low. Only the first index may be omitted; it defaults to 0. -The core type ofamust be an array, pointer to array, -or slice (but not a string). After slicing the arraya@@ -4267,8 +4178,8 @@ No run-time panic occurs in this case.Calls
-Given an expression
fwith a core type -Fof function type, +Given an expressionfof function type +F,@@ -4298,6 +4209,12 @@ Iffdenotes a generic function, it must be or used as a function value. ++If the type of
+fis a type parameter, +all types in its type set must have the same underlying type, which must be a function type, +and the function call must be valid for that type. +In a function call, the function value and arguments are evaluated in the usual order. @@ -4811,17 +4728,28 @@ more complicated:
C has a core type
- core(C)
+ If all types in C's type set have the same
+ underlying type U,
and P has a known type argument A,
- core(C) and A must unify loosely.
+ U and A must unify loosely.
+C's type set are
+ channel types with the same element type and non-conflicting
+ channel directions,
+ and P has a known type argument A,
+ the most restrictive channel type in C's type
+ set and A must unify loosely.
+P does not have a known type argument
and C contains exactly one type term T
that is not an underlying (tilde) type, unification adds the
mapping P ➞ T to the map.
C does not have a core type
+ If C does not have a type U
+ as described above
and P has a known type argument A,
A must have all methods of C, if any,
and corresponding method types must unify exactly.
@@ -5372,10 +5300,10 @@ var x *int = nil
-For an operand ch whose core type is a
-channel,
+For an operand ch of channel type,
the value of the receive operation <-ch is the value received
-from the channel ch. The channel direction must permit receive operations,
+from the channel ch.
+The channel direction must permit receive operations,
and the type of the receive operation is the element type of the channel.
The expression blocks until a value is available.
Receiving from a nil channel blocks forever.
@@ -5391,6 +5319,12 @@ f(<-ch)
<-strobe // wait until clock pulse and discard received value
+
+If the operand type is a type parameter, +all types in its type set must be channel types that permit receive operations, and +they must all have the same element type, which is the type of the receive operation. +
+A receive expression used in an assignment statement or initialization of the special form
@@ -6126,8 +6060,7 @@ len("foo") // illegal if len is the built-in function
A send statement sends a value on a channel.
-The channel expression's core type
-must be a channel,
+The channel expression must be of channel type,
the channel direction must permit send operations,
and the type of the value to be sent must be assignable
to the channel's element type.
@@ -6151,6 +6084,13 @@ A send on a nil channel blocks forever.
ch <- 3 // send value 3 to channel ch
+
+If the type of the channel expression is a +type parameter, +all types in its type set must be channel types that permit send operations, +they must all have the same element type, +and the type of the value to be sent must be assignable to that element type. +
The expression on the right in the "range" clause is called the range expression, -its core type must be -an array, pointer to an array, slice, string, map, channel permitting +which may be an array, pointer to an array, slice, string, map, channel permitting receive operations, an integer, or a function with specific signature (see below). As with an assignment, if present the operands on the left must be @@ -6958,6 +6897,12 @@ for k, v := range t.Walk { } +
+If the type of the range expression is a type parameter, +all types in its type set must have the same underlying type and the range expression must be valid +for that type, or, if the type set contains channel types, it must only contain channel types with +identical element types, and all channel types must permit receive operations. +
The variadic function append
-appends zero or more values x to a slice s
-and returns the resulting slice of the same type as s.
-The core type of s must be a slice
-of type []E.
+appends zero or more values x to a slice s of
+type S and returns the resulting slice, also of type
+S.
The values x are passed to a parameter of type ...E
+where E is the element type of S
and the respective parameter
passing rules apply.
-As a special case, if the core type of s is []byte,
-append also accepts a second argument with core type
-bytestring followed by ....
-This form appends the bytes of the byte slice or string.
+As a special case, append also accepts a first argument assignable
+to type []byte with a second argument of string type followed by
+....
+This form appends the bytes of the string.
-append(s S, x ...E) S // core type of S is []E +append(s S, x ...E) S // E is the element type of S+
+If S is a type parameter,
+all types in its type set must have the same underlying slice type []E.
+
If the capacity of s is not large enough to fit the additional
values, append allocates a new, sufficiently large underlying
@@ -7473,14 +7423,14 @@ b = append(b, "bar"...) // append string contents b is []byte{'b
The function copy copies slice elements from
a source src to a destination dst and returns the
number of elements copied.
-The core types of both arguments must be slices
-with identical element type.
+Both arguments must have identical element type
+E and must be assignable to a slice of type []E.
The number of elements copied is the minimum of
len(src) and len(dst).
-As a special case, if the destination's core type is []byte,
-copy also accepts a source argument with core type
-bytestring.
-This form copies the bytes from the byte slice or string into the byte slice.
+As a special case, copy also accepts a destination argument
+assignable to type []byte with a source argument of a
+string type.
+This form copies the bytes from the string into the byte slice.
@@ -7488,6 +7438,11 @@ copy(dst, src []T) int copy(dst []byte, src string) int+
+If the type of one or both arguments is a type parameter,
+all types in their respective type sets must have the same underlying slice type []E.
+
Examples:
@@ -7538,8 +7493,7 @@ If the map or slice isnil, clear is a no-op.
-For an argument ch with a core type
-that is a channel, the built-in function close
+For a channel ch, the built-in function close(ch)
records that no more values will be sent on the channel.
It is an error if ch is a receive-only channel.
Sending to or closing a closed channel causes a run-time panic.
@@ -7551,6 +7505,12 @@ The multi-valued receive operation
returns a received value along with an indication of whether the channel is closed.
+If the type of the argument to close is a
+type parameter,
+all types in its type set must be channels with the same element type.
+It is an error if any of those channels is a receive-only channel.
+
The built-in function make takes a type T,
+which must be a slice, map or channel type, or a type parameter,
optionally followed by a type-specific list of expressions.
-The core type of T must
-be a slice, map or channel.
It returns a value of type T (not *T).
The memory is initialized as described in the section on
initial values.
-Call Core type Result +Call Type T Result -make(T, n) slice slice of type T with length n and capacity n -make(T, n, m) slice slice of type T with length n and capacity m +make(T, n) slice slice of type T with length n and capacity n +make(T, n, m) slice slice of type T with length n and capacity m -make(T) map map of type T -make(T, n) map map of type T with initial space for approximately n elements +make(T) map map of type T +make(T, n) map map of type T with initial space for approximately n elements -make(T) channel unbuffered channel of type T -make(T, n) channel buffered channel of type T, buffer size n +make(T) channel unbuffered channel of type T +make(T, n) channel buffered channel of type T, buffer size n + +make(T, n) type parameter see below +make(T, n, m) type parameter see below+
+If the first argument is a type parameter, +all types in its type set must have the same underlying type, which must be a slice +or map type, or, if there are channel types, there must only be channel types, they +must all have the same element type, and the channel directions must not conflict. +
+
Each of the size arguments n and m must be of integer type,
have a type set containing only integer types,
@@ -7925,7 +7894,7 @@ causes a run-time panic.
The protect function in the example below invokes
the function argument g and protects callers from
-run-time panics raised by g.
+run-time panics caused by g.
@@ -8483,17 +8452,14 @@ func String(ptr *byte, len IntegerType) string func StringData(str string) *byte- -
A Pointer is a pointer type but a Pointer
value may not be dereferenced.
-Any pointer or value of core type uintptr can be
-converted to a type of core type Pointer and vice versa.
+Any pointer or value of underlying type uintptr can be
+converted to a type of underlying type Pointer and vice versa.
+If the respective types are type parameters, all types in
+their respective type sets must have the same underlying type, which must be uintptr and
+Pointer, respectively.
The effect of converting between Pointer and uintptr is implementation-defined.
≡A
+ type parameter, and all the types in its type set unify with
+ the other type
+ per the unification rules for ≡A
(loose unification at the top level and exact unification
for element types).
Gm=kH=(jS;BnBltEzG3Jq?C**DE&2=1mSV!doo%)^jnfj+_WzY*_d%Y z-g<_ixHDG&L!5EX^kFJ-{l3z7B^3AkySV36+y*Lc!>{6cs>LZBzA@Rx;?80JT~P^r zX2kvo8BZf36yG_1w-FZP2z3-iP1)nk#6?CG0VqMR0seJnXStG<#Nr1JY)a*|yjk%C z-g65JBk-9w8_x(B?55AEWC7P!CWCFRygB@RkC!OM%h;ow)`CY@+t58%2(8`OXoF5j zP59D1@k#0nfkGzZOZH*+V+GrZ@Xejjbs5?9 zCgl-!5wi)qn0Nv19OQ`T=_-S%5}{PFZ8H0L0Jle4od#RaunXA%X^ _~>YKhI+jcowj8(LVRZXkVKzfcDvgRWaL4@u`5_q0Ln!u1bL9GIqYk z`b4DgsDt(iti7VgRko|1ICWTHToEc$1REb<%v3U}eWWQ-ciF1WwlJ}ZwGz`UL?9SF z91d5pT@(W!vUANjjeQ>nz%?biPnh~OUy=HbJHRSjghE9Van_@*6K^Ba+fZ*ToMb@u z0J1rKXWBKGFm0 48DDtYB$L4Nc0tJ$p0T6t7esL_X~Tu|KngEbT%sM9R@qX#B<}#lFGq CpitlMTjN*Ik<4(~ZDI*_In5wZ;1#5=t z5Qb^bmQXz1{vpNF3nx%Kqk25W_wVga@dG9QQJDF+BZUVKT2Oc>rkf7ola z6rS9WNn!r+5fq-9okZd3y%$ulVg&W*nZYw+2!ETiacAj|bL|IGSP=HUj&u}SPouD? z(;>K$$=QLG0jCMdvz&&otdIZUshk%Belxi?B2GyD0n?Ll4#51gmQ1|iF0x7CZwx0c zQ-Ci;hWU&kea*rP9H|u}C6UpGyj9SgPHsgVWiIVxAY0A3DQ2_W`j+CPFFKA>FuhFy zlU7``i!1UaVMQ-ABbHvyCR$F_sdXc8lf|kq3a_6iC9o)HPzizdg5zLPx#`_MbYa!65!2=%yoO#JW%-b;8rnQ(ZX%N zsi-O39$u-??Zx#I>Z!cS@pu?#8D3tm@5qQCJc4uU_;nl6LQnGjj#;GzdKfj5(C?;H zFM696h#n?)twEj1r@unx&H1q0Ukg4?hpE0?0yq5fO;@7M8lL@p2}=8N{S_6RxVxNq z;ry^rl?|u6bCHd0m^0Bw@c(JUH}aPE|7HWA4bBRiU@pXfYyU375N3yS3GBPaaQ`39 zoyMnPOe%+7)7=b~tGUjK_%U3hNZk8Ls+Awkn;*Q1z+f7S;>o1Y%fZDvGE^@?>L9vZ zM<#3Y%e|EZZrSx;3?#CA)3{32T1gJuO$oNgKB4(^hm#@2cg~HFkO8~g6DYoWq+cSz z_q24U_+I-oOpi)siUULORE>=if~VHF#SobGESmQ3ySann>4m`*&p5xA(nG5$Tyw)o z^!K3{Sv(n&HEmf8gm`joV5?HNoDG!0gG8a7a7v~`A>;VLbdhSnOodQio@` ahH Er(MU(S0t)Wb-v5g{XY_fku{kZAcyfA_nDSC(fmK`9>nA4o}>VQ=uA*f2} zB_XhSgAau@%bX~zooz{B-9!n6^@AA-Uw3^?;Tz9K6uz~;M&Ub?a}+j6>JkaR_s$}U zzppDhyqy!%$?1RwYZ*ao0oNJ)=5acT7t1(v6E3Sle-xf`(PHytZZiAY`;P!O=%fm8 zgB@Iwh?_S4&05%-!o{++6aOGJGF6eLr*U&xty{es-q+(1x1Ir61{c-3CHf1MP-WK8 z>#8Z6KVbT3qVmtodb>^$&+*y} jHRrBq zn#sM_6(>%2@Vtit??KZOTm;NZ=5)EK*SNKckv5zub%HH&(5zB9p}3hyqVUY;0wmn| zo*fHeekmIDcG(|B>3yI^!JYo-w13LD>G* X!&n1@=e~h1%lW_)d|$mg`6(D;Igr>nIg}X-zet7 zwJWn=s1Ki@p+oM~Q#eQ+%C~||b{KliefdLTadC^B2-VBk^{)KSmop 0zW2guhi6(=IN8wk|U0+lOziXz0#=D#K&gR>PXac$`7veaN1 zB!u!SAt;qKaK#&1Pg^2x*)H;p(}GUgm`M&$I8i$ETcTPCUV^T8q0zO!B4hw>!EyH& zC69vXL-++E(~Bs2Gd%F&TXQZYqgug(fxHoT4&^6lXp-7b`d|glU}~>l{vZQ}@8xAu zb$J~nWuH{Tyjj+u#r45hAcn;l0>)8Zat_x0I^O;D1m` zHDM!CaHOaW^%=Y|`$QA2lQHV*^&ey8VvwXF_wicLGZiV-6=|f@|DghfcG|EsmA96v z>&w{M*rpHKa3+ i5h>;CSJTzd#76zXay%4zH{$JVeFDQG=Y z#a+h%?xZ94TnD*-tES+X!8@?2jxZ>LH 6_a^Vg}!Vjdg;H8OV=RCRO}q z%0RpyC!7=|RR-C(K&SnDNA{`7r zLko>6gA&~#;{ZmXy2glO8jJJwfaeEzFCV3cT5Rv|n3*%C{4Q2qT>OJYh9`{7L?P<3 zAyPE<_{{e3UnT~dx?+eFjRV=v3$ABkAiwj1CI`{q1sx#xAkNXjj =glC=1&YyFx9&7xjeJ*}RQZUB>&v(nWn?Vm9AGsxI9j zMdLVk4Te40$n#w=JjzBLX7rbb4>JOf!@LJOV<7%+3X2Z&?bxY9@V7BsBJI n$~fCb?)-zzXooMVcimVL>kTb@&HzaxtXT zB|+rcI6KW-18;MAe|ByXcpO7F4q6K{kKxpLtb>EckVCispz0X*`)-!s-)I7z^H9p; zZ7?+t+e&sqRvywC?Sa}noC@V0XmcESyiSEl$1!D)G9n}%$51+w1}Vpp@~?gH_&8F= z9s=tVNEvom&SaawUnh`jcn<75!3VIdkHXUvNYgwIY) 4r&}hS*KylNutadNIr>9QrGqVpbRdA3PNdABu_qN49@weE?*48@` mZb83OI7tU@K_Y>vccFy9mG?pCH1EeoRYLF6h+laO zD+!+V5-y&`O}n}Zbk3mD1hvqUz-_N##TnFUO#>7Xyy^>x&hobA>hj u@ImaWW}s1s%cMjKeG74A=v%`2LOwv4WyQdy z=1g;VTZmpXwE?Rlq)urG vW^a(?t? Ga>#m z((j)QCod!2-ua-s%(vi3-Bp!)S1babQj&YsrPbee3-86SpcG{dTn0x=k$327cwb6% zSr2YkFg-YLgy<`LN1^{_27>=%q)>E)cMz^hrkF8km+>;;&RyTJ&@$eYJ)Q!~%W!0R zI-Ds(PJ0imzls7TW`g%sG@>pG7F CG*W0+^sjIn2(fAa*O$pO(^S;8d0v57v^Zr5& zmW2jvVL!3paR)W5;$Z3>^iP>K9J)g$S^~9qFwv-MyU4R~f-^ONHWf%&XaW%x7;df1 zA*BL6$y>nV3gq0O1=!w2AI!3c(RYz I6F~aYS%ucu>i=l#&82y$C>c@FMS*C$Jl|c)+`}HQivy z1KyKO=m|*=FhzC8Vh+KF^aJ5T#P5ef$A^ed83Z#PqK6HJz=4P8pX{OV3fsLqk6;A> z(<8#21H&gw92-9N_pL=;C`Q?h-wK|Lf{~AKDdmO1hDWH$g)wlM;Qx#T@neK36Cmg@ zO3sLc`H%6fkJN|3*GXi|226${q=$=!+Q+Dq_7re $b &>fhW8a#Lsy><{_9q=i4)DAp`+CAQ@IZ#~GNi9nL@JJ1{$ddx5;o_Ja2d z?Dk26Suaqg=>a%M@D7>qir|uiVD}P*MIVOIFOlB;2y7&H`=e0)66vCHLGlWr*)izx z3fVq~B?M$cJ^@eR^DEwqsRH*Z-o}iSylF`v-+LP`EhS8^;(cwM&V9F}=gct^Bcdn# zK3B9Hp8t+FW;Q@o6-w<=2zJ%zktHyqn)gJ M>rRL~+0evw?-4Xh0vRK6W|yyra7N_HF53d@8Bs^p zXBS*$M0mJQ1$`Fb;7sVrVte0gSjLL{*z#j=p0vB20$zytqchM&C~D6d7D2pF BD~|9rYrJdJL*D)F1GJ!0xxt4T~n~r!}cwv5UwY}*BLWN z*28u)E4ZtN a1nt{UTr#&7oNy&%B=wP?{F@^B=3dmwx 6pt-UK}`Xew-KBJ$D^&itXRb8kpc z;6mRg5$UWq!qstUHb{(+X~kUVV aso;T$*8j-f@`H41-2p z>cffqWwl|RGRcSZW@x|VX?WTUIej|^Et(^zV?{8cIpQlXz< zkaQOZb=>Q>M*<1YKOpRc0bR(Xv~dplhJ2K`O<` zes&+)NHG=mdL>$-7fDS>4dv%E`5EnOtLlX3$Usx6YWv<~rHMQf zpM!%r<{!Hk5N +KrAw4e z{_E1u=R-AoHOH;ud=2 VEfK z9n=#pq;#m_va=rASc+Px>Vx!vH}Ew?T4E@2Z(ye-PV)ITP>B>$b%_w=G(O3sy#)&^ zTn3~l_~SjKF~yK~Fcc|Nr>$5kkuk5;fX;wYJc2=v75Z@SM<}uqwPW{xg)de(KXyuR zvBsUu0?S%Z)e7^tRTi(a&Wh(?wY5l##k-SD*w4OZp~M=uV$88h0;g+&tObrw(}8g< zFrf4eU}p;qu<9mopFj%}FtZUku_5?pX*Ni=)dJ#eMC~-LwcrK8{eqzFg+DgeSX+2P zNDsD#=C&Ba(;Okx7FlOGLz1n?pWQEmYql8u>T)JJsPRe^x`9DUjM;iO=+zRH$nt_^ z1b6EQXIf$m>w5!hhpxWv4SsewVYEOQZilOWr7z5}Ls@=)ps+(qbAM yb?6=n@}f%A{aWV(ZO zYoyfZ0V7%?rMiUq2j!_Au$fS+G_sqcyX8K@$hm#k)83c0e5m_JI`+*x#)$6gZ&n z;$Yw%k*+8h{2ei%)Fn*h+;}ru9RjhA$RVj89CJhto%+LjNA$EL6ujD?PU>nT=9$KU zc6|WMZX@cTJ#Y|CXZVIocS4>y!(pHkE}wZLV6_tlbcb*_<0Nup zO(wucCp^V@M(~1ueS1R8Ys?EhoiX&^N5U{?k-L^f6fX#!Ic?IoIjXbB5$x1>9m5L- z1ck!aEF^zM$QMop{7VvdcJ54YlA)leIWR$nho{AJVH<%<6X1pnoma33j9d^uu>yLz zApPl;u*gN^qyJ(xa_sNiI|APhCxl0nOCTw{azW1P MkGF!BE1q4Gc7V65$k`$?g%_w!Q9K?G T1cHI=KsJ4qK=2vc1%m$rpyqfU delta 8917 zcmZ`;30RG3`# UR3^^{N<>#gytg{dnBz zEZ0YB8OPKk+m4XLG7Ub7sizp`sT&0-)nP^|(rhoOnJXvgs%b@zDW|EI26$#CG>S5j z0<|?#7ugN_ (sL6C`KFjtyeWPIHRZlLGxQ%t(E^_3%&S z5Ce^L)dortS*d;8RN9D6y4@42qEz1rHc}t<81~si_7cx3xmI+Qw^meg+0jR(o1aKF zRag3)llZ6GCN|(}bDQluiJBsbxcD`QT3e!reu-igwH|l-f8{Z@-M_`RsZY8o)h7bt z)#2__wZE4Ij@SMcQwa-7_>zVqcrhpW{k1~_LsFq8bQB$nGb7 -n!PLZrU}juk}K6~`X-18t3=FNJ-FX6Etai_8tf_wjGv)(tIBqmnaHbCa+K K8rtBq0iWHLXsVC}vH#_;f-dxkGQgGS1SMyqFr7|Fwq_qAJESGENRi(Kj zm*>ovi0c>B6Y-Aclo d0OCHB^R@>+0%neP6MTW={^u||j$CxxuJWW}Ab z!MY(#sj!jBkbZ~R;)D-3kgBPV&|$2HCaEoVibq}uh21HDo1keQ%AHnd#szch^l`n6 zsOAyeGz@;md29AYaNs54H{G~YiCEi>tFlDh1Cp#8!Hv_lY1Tt7LQ^o3Tc|{bW5gJm z#Er$aV_Y@#9y3!-vt+I;hVK%PXa}>S+; H^ZJ^ay|4}#x%ti#q;1W zO-s3AoTVfSE5-OPvgy`}X05a{jNA~#gik~L{yj6rgK)(riS=uz&n!(;gu?95N(F_I zEaww6%U3A$cug+jSGGiM6JCipcRo>*)lM;;gR8k ppauUQxrT%i z1Z@)- NBZLoGx!QPL> ze_2a)er%Ni-%b-f6Kg`)e8dc9UYg#aEZ+b{vCJB+yR&b^Aw%?F=7T0Z*gk_P1vAI4 zkjZ2#aHR)J)S9|Ih;`De@5yQy*7c{XH%BoQ)`c-+j1Fhs8lpug47zmxXfd4XJsi(s zSfYk?VwUp1#|&b; *KDRVHK!=P z{2L-yXDKZ3;4mFkD&AE2h0~qG&CSe7Qfl;tPQQBcu=$4t8T&JtEPUJ~)#x~{@X1Mt zs%DL~-b{7H9R)1=hdFAGjRveU0t!Ty7-Iw07Co>nEQpKMN7xn;sog;}a?N7KoV5XF zZeh-nJ>7Ip8X#v2Yat0g*+Rlw4N<*?b>M~>q1{#%$gMX;>Q>f~>u-(iTbYAY9jnbG zxy=?&w^G7lEDm24f)f6w>E}c{$0f#1f=xEFGqunuioP92WU^LLy-ajiHFo%KCToVF zSHwQ QDDZueoP}fszxv8yDxQ#5daDmZw7Roht zMX&A5UW~(*6Wp v@34V4VtNv_Nd9OFBV*O z5oJ*a1n!~<{U4PL?uc)9(P-L-K(mWHR)yfT2sehpXE%ACAC9EmG{O@i@b_+_TXn$$ z5jX4shdtyZ?-n&nHwnW&7`BHdPh{ckIr9Is4_5CX Jk%wuiZKUHYphj 3hiZQt=P(~GY&gPmSOnKPj%arHGly)n8KdRj6Zx&< z)f2}%!GAB&TPGlHFUcAwsV62{s*{ri ?7TlQ? 9%?O~=uF)cD%zsM|-0&B~+1Y{XK>&q2ri)GxQWn7N+ $O$WUCMUL@$>)- yjOno2`=ljC=aa#-BUqMC&NrUG>3m9QK>->aA^h+; zbU#Az{*RfOScD&rP$Byj A&rZ0uetH1>rp5zxPMPd6J(KjRoha(xYOKf1XO$DRyNc zv3-Z4V mGn#@1?N5n)rI6VE*?P_NNKkU(=L#fCI!1Lkk*z- zcy)n{ub&FvqE9=G*emWovoW!V8fsGfuaO@=2Rn)=!tM+4yoii;T>|%FGU}?v_+l2Q zYzDb3JZY@ jII?a54!^DfUFT5?LO=IpF2?@PO$jbkUNDnS+0}fuKQmx&L zs*7ZB)mHdjB1c0rk$Q=;xSxd`mnhnEJ5YIv_+>lcd6~ILL-+A4P1u0la?Ht*TVnBL z%06%pc3&oW!yLT1%t95%_R5iWKyHDaCB*%EAEuR1>sRMuZwXnyb` }H`Ctt;mtHk%ej&c!Z-hsz8YOMV|q+X*M z^N+Co8p#=#qVgK?`@DeHb((VjmvVT&p;+f%r)X?mA@h2D2O1m$Yu=&k|6$E~57!%? zv~*AUp|yy=QGc#L+tT(Qu<-^9QP_QyXUyj;@! w!-ktw zjvo#1=q9E4q7j dt(>D=W$t$~oP7 LKhyZsl4JJ=0C`?1oCuBM2TP%D+Vkf5K z;1g0iItSGvUOX4xPbrf1^AP`(wUbBTkEf(o`W>!`F#iWwmNI{N3VM~YK)Ev(65#Hw zMQ$k-xpo~sl(JyC7Xr)3)~1d0{z&YC&G@H`d~Dc;ha!GrI~<=8z9tJpo{`b_yRh;Z z$>;CJIT1gW1H E@(#u%@C3vcw%p^cjK}MqyQb9`E zFVFE6G#x(|;oAxl>wv5Z3VHt}lvU6e uL0xyo)~Z6#|eeJ-DH7L4T! zaES!u-C+Kb%Aa^2eP5FOKKSt^Su;jHVch1&_$X2%5%h{;aKq$R6yTLIWWJ(~K7WQs zBH0K|ugS!QN(_5VRhsY$8Lx@#g!4p}_kz(IT6Uvq(CZB;{rDaW-w?Msa^EmVd-3t5 zjY1|9|Le|8ejSJRZ>SDdX#198nWBf}w-j0cHom1q-|OS Cy(HC?O4SD*%Wr)!p&S4|H7u)=|AQr&5bch!{UVSD)1 zkm?2pB-K#E&N?HrhUoiS;BgI^j&nnccO<{e6QkY{zRDYG-%$uNd~ip^NBYA4J=u-) z$Kdy*-!2fpy{8RFd$ZTx 2(XwOw9Wh@}jFC`;S2;=@r1t%v| zH3gw^fg<}Bv*khv7d#6GMfh?qKFEb&uHSqFaU}1x5HmR;fP41?c5x)HT#T0@{+y0$ zg%F^(^Jj%DB60vSbLqoM@2gE%CTpffhC=Y=oL8YhK`t+^gB~vg8=7t;mAK@%F>&bS zD_CRG5xT#p@PaW{xfOGHl6;bd1H2H*rR3lPX(-MfR3Pdwy;1aGf*Ut04>On$$Za`_ zT} ^fFEe6z}bus1*bs&hb9H^aO9t<|*Rzh@SZrEA<3_E}|4?MR>gwyuQ$mODjVM z5t=;16cKKIhOPR<4}XsPBE0$>wgv B5g-#+=y~Yd?@^7$HglpfR)QIE*-@;i*@WNZfiZG!H z%S5QC#&Hq;UX2eT^sj+mBZB8@kVsHJ{vB0h%4jcmItorW*+?+ful+ KWVEiTG-w(wN3&Bx*{I%uA#lflxWin|rVww<9 ztXhM}Z_wYmno#6Jl5xHX*%v0k(30#GrlGT?(82Wfv`@i!^;RWMPQ*+r!LGrplg~^X zuq55gxu_y&K4!sZoj$73DRe=BrzvUa?&=R0BH4-}KEDWmTam{eOL5nVf*rUFj@D#t zzzPhpCcbY5)FL$b4QE8U11vb=RwgI^$Aw3~` z+6$Ik#wL8UA>BXzL6EKBAhl3;e5^Au*_Pbv(VgCwj9lJ{=eDFWY&Tq*lJVI&7~7Qi zf9=O#O{s6GW>ibvE7He Ri}=D*IBQ2H)}Miqz2Nv& zd - 0x$c_RMoGTz(Me(_xiyd4Bj?(R*DbP#;?A|LRwuDu7Wbfoq2 z)PYvlC5hk;A4kDnBE>({%6Ld5J4c$ZnuloPNZZhlk1*U(@Yi#C%*(pb#&w~THm*IQ zgu@dYcNF}%o@J;N*Qxf6xA9lIpG@|$3_eamXrp`2cv<)4F{-#^uZZ!Om&GikBUQJo z8=fQ6iB^KcEBfL}e1S42D!
doYruxLgS;v=Q`fLEX6>K!*dWy+MXX#ezIPj#WM@pCi5$?of02d|T7#cLEa zqhf_rqqdpQmiwg^-p#2O%8wY^T=3!fI$j1RcPdhLb6RVH4CjfgcSX)*z3F&JY5T8} zqnki1D)-&|e;sgx^)RLd8DDOM-&)X!yfHyZ3mTbXb2M&AkhetNmNWnXwwT*e@HPD2 zp2_;eO^r)PfwS1WD=q09+ULw<{rX2B?krIZT2VX4G>1(qG7A^ xM )+q%DJzrDgJfi2O^07bqAzdM`XHC# j-XqMXiH lC$lLDIVffx{^uVH?zBavD1T8f9Z#E54v-7iDHP0rfP?KQnk(d zBgvCuSt2Ux#!?cEt)Ap7E(T9L$%n&0H1{I>{6LHl;ru~Z?L{%HiN!T9!NKk8s_Je< zaf83~V^Cb;SonI8YqKHf<4tys48f1yLV)nYP?Ac4+)1!No&}xAkG*MVB1fRgoA!Wa zW8vW=cyXQLF 2qP^OGUacAKiTE%5iED=J}H1*~QTKQjV{e z;;k k%vNKapWw%zTFqqWV@z8{l^^*ZOs9fBsh9tb5Pw>=Yt|vv jU+{8B+sI@?(k7(!>&XOhAY-@~E@_EOCj3o*ZIb;TcSS2A diff --git a/lib/wasm/go_wasip1_wasm_exec b/lib/wasm/go_wasip1_wasm_exec index 3b2d12ec..2de17587 100755 --- a/lib/wasm/go_wasip1_wasm_exec +++ b/lib/wasm/go_wasip1_wasm_exec @@ -14,7 +14,7 @@ case "$GOWASIRUNTIME" in exec wazero run -mount /:/ -env-inherit -cachedir "${TMPDIR:-/tmp}"/wazero ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}" ;; "wasmtime" | "") - exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=1048576 ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}" + exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=8388608 ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}" ;; *) echo "Unknown Go WASI runtime specified: $GOWASIRUNTIME" diff --git a/misc/linkcheck/linkcheck.go b/misc/linkcheck/linkcheck.go deleted file mode 100644 index efe40096..00000000 --- a/misc/linkcheck/linkcheck.go +++ /dev/null @@ -1,191 +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. - -// The linkcheck command finds missing links in the godoc website. -// It crawls a URL recursively and notes URLs and URL fragments -// that it's seen and prints a report of missing links at the end. -package main - -import ( - "errors" - "flag" - "fmt" - "io" - "log" - "net/http" - "os" - "regexp" - "strings" - "sync" -) - -var ( - root = flag.String("root", "http://localhost:6060", "Root to crawl") - verbose = flag.Bool("verbose", false, "verbose") -) - -var wg sync.WaitGroup // outstanding fetches -var urlq = make(chan string) // URLs to crawl - -// urlFrag is a URL and its optional #fragment (without the #) -type urlFrag struct { - url, frag string -} - -var ( - mu sync.Mutex - crawled = make(map[string]bool) // URL without fragment -> true - neededFrags = make(map[urlFrag][]string) // URL#frag -> who needs it -) - -var aRx = regexp.MustCompile(`]+)`) - -// Owned by crawlLoop goroutine: -var ( - linkSources = make(map[string][]string) // url no fragment -> sources - fragExists = make(map[urlFrag]bool) - problems []string -) - -func localLinks(body string) (links []string) { - seen := map[string]bool{} - mv := aRx.FindAllStringSubmatch(body, -1) - for _, m := range mv { - ref := m[1] - if strings.HasPrefix(ref, "/src/") { - continue - } - if !seen[ref] { - seen[ref] = true - links = append(links, m[1]) - } - } - return -} - -var idRx = regexp.MustCompile(`\bid=['"]?([^\s'">]+)`) - -func pageIDs(body string) (ids []string) { - mv := idRx.FindAllStringSubmatch(body, -1) - for _, m := range mv { - ids = append(ids, m[1]) - } - return -} - -// url may contain a #fragment, and the fragment is then noted as needing to exist. -func crawl(url string, sourceURL string) { - if strings.Contains(url, "/devel/release") { - return - } - mu.Lock() - defer mu.Unlock() - if u, frag, ok := strings.Cut(url, "#"); ok { - url = u - if frag != "" { - uf := urlFrag{url, frag} - neededFrags[uf] = append(neededFrags[uf], sourceURL) - } - } - if crawled[url] { - return - } - crawled[url] = true - - wg.Add(1) - go func() { - urlq <- url - }() -} - -func addProblem(url, errmsg string) { - msg := fmt.Sprintf("Error on %s: %s (from %s)", url, errmsg, linkSources[url]) - if *verbose { - log.Print(msg) - } - problems = append(problems, msg) -} - -func crawlLoop() { - for url := range urlq { - if err := doCrawl(url); err != nil { - addProblem(url, err.Error()) - } - } -} - -func doCrawl(url string) error { - defer wg.Done() - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return err - } - res, err := http.DefaultTransport.RoundTrip(req) - if err != nil { - return err - } - // Handle redirects. - if res.StatusCode/100 == 3 { - newURL, err := res.Location() - if err != nil { - return fmt.Errorf("resolving redirect: %v", err) - } - if !strings.HasPrefix(newURL.String(), *root) { - // Skip off-site redirects. - return nil - } - crawl(newURL.String(), url) - return nil - } - if res.StatusCode != 200 { - return errors.New(res.Status) - } - slurp, err := io.ReadAll(res.Body) - res.Body.Close() - if err != nil { - log.Fatalf("Error reading %s body: %v", url, err) - } - if *verbose { - log.Printf("Len of %s: %d", url, len(slurp)) - } - body := string(slurp) - for _, ref := range localLinks(body) { - if *verbose { - log.Printf(" links to %s", ref) - } - dest := *root + ref - linkSources[dest] = append(linkSources[dest], url) - crawl(dest, url) - } - for _, id := range pageIDs(body) { - if *verbose { - log.Printf(" url %s has #%s", url, id) - } - fragExists[urlFrag{url, id}] = true - } - return nil -} - -func main() { - flag.Parse() - - go crawlLoop() - crawl(*root, "") - - wg.Wait() - close(urlq) - for uf, needers := range neededFrags { - if !fragExists[uf] { - problems = append(problems, fmt.Sprintf("Missing fragment for %+v from %v", uf, needers)) - } - } - - for _, s := range problems { - fmt.Println(s) - } - if len(problems) > 0 { - os.Exit(1) - } -} diff --git a/patches/0001-Switch-ProcessPrng-back-to-RtlGenRandom.patch b/patches/0001-Switch-ProcessPrng-back-to-RtlGenRandom.patch index f7892281..8dcf7811 100644 --- a/patches/0001-Switch-ProcessPrng-back-to-RtlGenRandom.patch +++ b/patches/0001-Switch-ProcessPrng-back-to-RtlGenRandom.patch @@ -1,6 +1,6 @@ -From 8dea0c5555bd5f397aa11a4e052bbec0d71e6495 Mon Sep 17 00:00:00 2001 +From f406141ab7c4861f2738d73ea5b77733ad0aab37 Mon Sep 17 00:00:00 2001 From: Vorapol Rinsatitnon -Date: Fri, 14 Feb 2025 10:39:55 +0700 +Date: Wed, 13 Aug 2025 21:41:22 +0700 Subject: [PATCH] Switch ProcessPrng back to RtlGenRandom --- @@ -47,10 +47,10 @@ index 1ca16ca..7d5cea8 100644 // - On wasip1/wasm, Reader uses random_get. // diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go -index c848f92..715d072 100644 +index 905cabc..94d280b 100644 --- a/src/internal/syscall/windows/syscall_windows.go +++ b/src/internal/syscall/windows/syscall_windows.go -@@ -416,7 +416,7 @@ func ErrorLoadingGetTempPath2() error { +@@ -419,7 +419,7 @@ func ErrorLoadingGetTempPath2() error { //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW @@ -60,7 +60,7 @@ index c848f92..715d072 100644 type FILE_ID_BOTH_DIR_INFO struct { NextEntryOffset uint32 diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go -index 6a6ea7b..9a096cf 100644 +index 90cf0b9..87d0b9e 100644 --- a/src/internal/syscall/windows/zsyscall_windows.go +++ b/src/internal/syscall/windows/zsyscall_windows.go @@ -38,7 +38,6 @@ func errnoErr(e syscall.Errno) error { @@ -79,8 +79,8 @@ index 6a6ea7b..9a096cf 100644 + procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procCreateEventW = modkernel32.NewProc("CreateEventW") - procGetACP = modkernel32.NewProc("GetACP") -@@ -236,12 +235,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32 + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") +@@ -242,12 +241,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32 return } @@ -96,10 +96,10 @@ index 6a6ea7b..9a096cf 100644 err = errnoErr(e1) } diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go -index 7183e79..fd65e34 100644 +index 04752f2..a6d3211 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go -@@ -128,8 +128,15 @@ var ( +@@ -127,8 +127,15 @@ var ( _WriteFile, _ stdFunction @@ -117,7 +117,7 @@ index 7183e79..fd65e34 100644 // Load ntdll.dll manually during startup, otherwise Mingw // links wrong printf function to cgo executable (see issue -@@ -147,10 +154,11 @@ var ( +@@ -146,10 +153,11 @@ var ( ) var ( @@ -133,7 +133,7 @@ index 7183e79..fd65e34 100644 ) // Function to be called by windows CreateThread -@@ -264,11 +272,11 @@ func windows_QueryPerformanceFrequency() int64 { +@@ -263,11 +271,11 @@ func windows_QueryPerformanceFrequency() int64 { } func loadOptionalSyscalls() { @@ -149,7 +149,7 @@ index 7183e79..fd65e34 100644 n32 := windowsLoadSystemLib(ntdlldll[:]) if n32 == 0 { -@@ -501,7 +509,7 @@ func osinit() { +@@ -500,7 +508,7 @@ func osinit() { //go:nosplit func readRandom(r []byte) int { n := 0 diff --git a/patches/0004-Add-Windows-7-console-and-process-handle-workaround.patch b/patches/0004-Add-Windows-7-console-and-process-handle-workaround.patch index be7526f8..325529f5 100644 --- a/patches/0004-Add-Windows-7-console-and-process-handle-workaround.patch +++ b/patches/0004-Add-Windows-7-console-and-process-handle-workaround.patch @@ -1,24 +1,23 @@ -From 017970028ebf60ec44fd1b528b691a47f09ea3a6 Mon Sep 17 00:00:00 2001 +From 4c18dbd71ffab945d87cbd5fa86a0027dd6248f1 Mon Sep 17 00:00:00 2001 From: Vorapol Rinsatitnon -Date: Fri, 14 Feb 2025 12:13:28 +0700 +Date: Wed, 13 Aug 2025 21:47:16 +0700 Subject: [PATCH] Add Windows 7 console and process handle workaround --- - src/os/exec_windows.go | 11 ++++++++++ + src/os/exec_windows.go | 10 +++++++++ src/syscall/exec_windows.go | 38 ++++++++++++++++++++++++++++++++- src/syscall/types_windows.go | 10 +++++++++ src/syscall/zsyscall_windows.go | 7 ++++++ - 4 files changed, 65 insertions(+), 1 deletion(-) + 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/os/exec_windows.go b/src/os/exec_windows.go -index ab2dae1..f5e3a4f 100644 +index 68c7064..6a44a7d 100644 --- a/src/os/exec_windows.go +++ b/src/os/exec_windows.go -@@ -44,6 +44,17 @@ func (p *Process) wait() (ps *ProcessState, err error) { - if e != nil { +@@ -45,6 +45,16 @@ func (p *Process) wait() (ps *ProcessState, err error) { return nil, NewSyscallError("GetProcessTimes", e) } -+ + + // NOTE(brainman): It seems that sometimes process is not dead + // when WaitForSingleObject returns. But we do not know any + // other way to wait for it. Sleeping for a while seems to do @@ -29,11 +28,11 @@ index ab2dae1..f5e3a4f 100644 + defer time.Sleep(5 * time.Millisecond) + } + - defer p.Release() - return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil - } + // For compatibility we use statusReleased here rather + // than statusDone. + p.doRelease(statusReleased) diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go -index 1220de4..b4b846d 100644 +index 3ba2fbe..77c0d44 100644 --- a/src/syscall/exec_windows.go +++ b/src/syscall/exec_windows.go @@ -254,6 +254,16 @@ type SysProcAttr struct { @@ -103,10 +102,10 @@ index 1220de4..b4b846d 100644 // to treat the entire list as empty, so remove NULL handles. j := 0 diff --git a/src/syscall/types_windows.go b/src/syscall/types_windows.go -index fa34053..f08ebe0 100644 +index 92fa796..c9749ba 100644 --- a/src/syscall/types_windows.go +++ b/src/syscall/types_windows.go -@@ -1173,3 +1173,13 @@ const ( +@@ -1183,3 +1183,13 @@ const ( ) const UNIX_PATH_MAX = 108 // defined in afunix.h @@ -121,7 +120,7 @@ index fa34053..f08ebe0 100644 + csdVersion [128]uint16 +} diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go -index 85c66de..e58a384 100644 +index ef00c0b..065977e 100644 --- a/src/syscall/zsyscall_windows.go +++ b/src/syscall/zsyscall_windows.go @@ -43,6 +43,7 @@ var ( @@ -132,7 +131,7 @@ index 85c66de..e58a384 100644 modsecur32 = NewLazyDLL(sysdll.Add("secur32.dll")) modshell32 = NewLazyDLL(sysdll.Add("shell32.dll")) moduserenv = NewLazyDLL(sysdll.Add("userenv.dll")) -@@ -170,6 +171,7 @@ var ( +@@ -171,6 +172,7 @@ var ( procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") @@ -140,7 +139,7 @@ index 85c66de..e58a384 100644 procTranslateNameW = modsecur32.NewProc("TranslateNameW") procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") -@@ -1237,6 +1239,11 @@ func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err er +@@ -1247,6 +1249,11 @@ func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err er return } diff --git a/src/all.bash b/src/all.bash index 1b8ca093..adbc60e3 100755 --- a/src/all.bash +++ b/src/all.bash @@ -10,4 +10,4 @@ if [ ! -f make.bash ]; then fi . ./make.bash "$@" --no-banner bash run.bash --no-rebuild -"$GOTOOLDIR/dist" banner # print build info +../bin/go tool dist banner # print build info diff --git a/src/all.bat b/src/all.bat index d5abec14..4c681d15 100644 --- a/src/all.bat +++ b/src/all.bat @@ -6,17 +6,11 @@ setlocal -if exist make.bat goto ok -echo all.bat must be run from go\src -:: cannot exit: would kill parent command interpreter -goto end -:ok +if not exist make.bat ( + echo all.bat must be run from go\src + exit /b 1 +) -call .\make.bat --no-banner --no-local -if %GOBUILDFAIL%==1 goto end -call .\run.bat --no-rebuild --no-local -if %GOBUILDFAIL%==1 goto end -"%GOTOOLDIR%/dist" banner - -:end -if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL% +call .\make.bat --no-banner || exit /b 1 +call .\run.bat --no-rebuild || exit /b 1 +..\bin\go tool dist banner diff --git a/src/all.rc b/src/all.rc index 45b1261a..ad8c3e14 100755 --- a/src/all.rc +++ b/src/all.rc @@ -13,4 +13,4 @@ if(! test -f make.rc){ . ./make.rc --no-banner $* bind -b $GOROOT/bin /bin ./run.rc --no-rebuild -$GOTOOLDIR/dist banner # print build info +../bin/go tool dist banner # print build info diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go index f966c5b4..336c9fd7 100644 --- a/src/archive/tar/writer.go +++ b/src/archive/tar/writer.go @@ -415,11 +415,17 @@ func (tw *Writer) AddFS(fsys fs.FS) error { if err != nil { return err } - // TODO(#49580): Handle symlinks when fs.ReadLinkFS is available. - if !d.IsDir() && !info.Mode().IsRegular() { + linkTarget := "" + if typ := d.Type(); typ == fs.ModeSymlink { + var err error + linkTarget, err = fs.ReadLink(fsys, name) + if err != nil { + return err + } + } else if !typ.IsRegular() && typ != fs.ModeDir { return errors.New("tar: cannot add non-regular file") } - h, err := FileInfoHeader(info, "") + h, err := FileInfoHeader(info, linkTarget) if err != nil { return err } @@ -430,7 +436,7 @@ func (tw *Writer) AddFS(fsys fs.FS) error { if err := tw.WriteHeader(h); err != nil { return err } - if d.IsDir() { + if !d.Type().IsRegular() { return nil } f, err := fsys.Open(name) diff --git a/src/archive/tar/writer_test.go b/src/archive/tar/writer_test.go index 7b10bf6a..9e484432 100644 --- a/src/archive/tar/writer_test.go +++ b/src/archive/tar/writer_test.go @@ -1342,6 +1342,7 @@ func TestWriterAddFS(t *testing.T) { "emptyfolder": {Mode: 0o755 | os.ModeDir}, "file.go": {Data: []byte("hello")}, "subfolder/another.go": {Data: []byte("world")}, + "symlink.go": {Mode: 0o777 | os.ModeSymlink, Data: []byte("file.go")}, // Notably missing here is the "subfolder" directory. This makes sure even // if we don't have a subfolder directory listed. } @@ -1370,7 +1371,7 @@ func TestWriterAddFS(t *testing.T) { for _, name := range names { entriesLeft-- - entryInfo, err := fsys.Stat(name) + entryInfo, err := fsys.Lstat(name) if err != nil { t.Fatalf("getting entry info error: %v", err) } @@ -1396,18 +1397,23 @@ func TestWriterAddFS(t *testing.T) { name, entryInfo.Mode(), hdr.FileInfo().Mode()) } - if entryInfo.IsDir() { - continue - } - - data, err := io.ReadAll(tr) - if err != nil { - t.Fatal(err) - } - origdata := fsys[name].Data - if string(data) != string(origdata) { - t.Fatalf("test fs has file content %v; archive header has %v", - data, origdata) + switch entryInfo.Mode().Type() { + case fs.ModeDir: + // No additional checks necessary. + case fs.ModeSymlink: + origtarget := string(fsys[name].Data) + if hdr.Linkname != origtarget { + t.Fatalf("test fs has link content %s; archive header %v", origtarget, hdr.Linkname) + } + default: + data, err := io.ReadAll(tr) + if err != nil { + t.Fatal(err) + } + origdata := fsys[name].Data + if string(data) != string(origdata) { + t.Fatalf("test fs has file content %v; archive header has %v", origdata, data) + } } } if entriesLeft > 0 { diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go index 2246d565..6b57f767 100644 --- a/src/archive/zip/reader.go +++ b/src/archive/zip/reader.go @@ -8,6 +8,7 @@ import ( "bufio" "encoding/binary" "errors" + "fmt" "hash" "hash/crc32" "internal/godebug" @@ -804,6 +805,9 @@ func toValidName(name string) string { func (r *Reader) initFileList() { r.fileListOnce.Do(func() { + // Preallocate the minimum size of the index. + // We may also synthesize additional directory entries. + r.fileList = make([]fileListEntry, 0, len(r.File)) // files and knownDirs map from a file/directory name // to an index into the r.fileList entry that we are // building. They are used to mark duplicate entries. @@ -985,6 +989,12 @@ func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) { s, err := d.files[d.offset+i].stat() if err != nil { return nil, err + } else if s.Name() == "." || !fs.ValidPath(s.Name()) { + return nil, &fs.PathError{ + Op: "readdir", + Path: d.e.name, + Err: fmt.Errorf("invalid file name: %v", d.files[d.offset+i].name), + } } list[i] = s } diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go index bfa35c99..410b2d03 100644 --- a/src/archive/zip/reader_test.go +++ b/src/archive/zip/reader_test.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "errors" "internal/obscuretestdata" "io" "io/fs" @@ -1281,6 +1282,49 @@ func TestFSWalk(t *testing.T) { } } +func TestFSWalkBadFile(t *testing.T) { + t.Parallel() + + var buf bytes.Buffer + zw := NewWriter(&buf) + hdr := &FileHeader{Name: "."} + hdr.SetMode(fs.ModeDir | 0o755) + w, err := zw.CreateHeader(hdr) + if err != nil { + t.Fatalf("create zip header: %v", err) + } + _, err = w.Write([]byte("some data")) + if err != nil { + t.Fatalf("write zip contents: %v", err) + + } + err = zw.Close() + if err != nil { + t.Fatalf("close zip writer: %v", err) + + } + + zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len())) + if err != nil { + t.Fatalf("create zip reader: %v", err) + + } + var count int + var errRepeat = errors.New("repeated call to path") + err = fs.WalkDir(zr, ".", func(p string, d fs.DirEntry, err error) error { + count++ + if count > 2 { // once for directory read, once for the error + return errRepeat + } + return err + }) + if err == nil { + t.Fatalf("expected error from invalid file name") + } else if errors.Is(err, errRepeat) { + t.Fatal(err) + } +} + func TestFSModTime(t *testing.T) { t.Parallel() z, err := OpenReader("testdata/subdir.zip") diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go index d589701e..5244ce2e 100644 --- a/src/bufio/bufio.go +++ b/src/bufio/bufio.go @@ -519,9 +519,11 @@ func (b *Reader) WriteTo(w io.Writer) (n int64, err error) { b.lastByte = -1 b.lastRuneSize = -1 - n, err = b.writeBuf(w) - if err != nil { - return + if b.r < b.w { + n, err = b.writeBuf(w) + if err != nil { + return + } } if r, ok := b.rd.(io.WriterTo); ok { diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go index 63dd2ea4..742e1954 100644 --- a/src/bufio/bufio_test.go +++ b/src/bufio/bufio_test.go @@ -1149,7 +1149,7 @@ func (w errorWriterToTest) Write(p []byte) (int, error) { var errorWriterToTests = []errorWriterToTest{ {1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe}, {0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe}, - {0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe}, + {0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrUnexpectedEOF}, {0, 1, io.EOF, nil, nil}, } diff --git a/src/bufio/net_test.go b/src/bufio/net_test.go new file mode 100644 index 00000000..d3b47e4c --- /dev/null +++ b/src/bufio/net_test.go @@ -0,0 +1,96 @@ +// Copyright 2025 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. + +//go:build unix + +package bufio_test + +import ( + "bufio" + "io" + "net" + "path/filepath" + "strings" + "sync" + "testing" +) + +// TestCopyUnixpacket tests that we can use bufio when copying +// across a unixpacket socket. This used to fail due to an unnecessary +// empty Write call that was interpreted as an EOF. +func TestCopyUnixpacket(t *testing.T) { + tmpDir := t.TempDir() + socket := filepath.Join(tmpDir, "unixsock") + + // Start a unixpacket server. + addr := &net.UnixAddr{ + Name: socket, + Net: "unixpacket", + } + server, err := net.ListenUnix("unixpacket", addr) + if err != nil { + t.Skipf("skipping test because opening a unixpacket socket failed: %v", err) + } + + // Start a goroutine for the server to accept one connection + // and read all the data sent on the connection, + // reporting the number of bytes read on ch. + ch := make(chan int, 1) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + + tot := 0 + defer func() { + ch <- tot + }() + + serverConn, err := server.Accept() + if err != nil { + t.Error(err) + return + } + + buf := make([]byte, 1024) + for { + n, err := serverConn.Read(buf) + tot += n + if err == io.EOF { + return + } + if err != nil { + t.Error(err) + return + } + } + }() + + clientConn, err := net.DialUnix("unixpacket", nil, addr) + if err != nil { + // Leaves the server goroutine hanging. Oh well. + t.Fatal(err) + } + + defer wg.Wait() + defer clientConn.Close() + + const data = "data" + r := bufio.NewReader(strings.NewReader(data)) + n, err := io.Copy(clientConn, r) + if err != nil { + t.Fatal(err) + } + + if n != int64(len(data)) { + t.Errorf("io.Copy returned %d, want %d", n, len(data)) + } + + clientConn.Close() + tot := <-ch + + if tot != len(data) { + t.Errorf("server read %d, want %d", tot, len(data)) + } +} diff --git a/src/bufio/scan.go b/src/bufio/scan.go index a26b2ff1..1a0a3907 100644 --- a/src/bufio/scan.go +++ b/src/bufio/scan.go @@ -260,8 +260,11 @@ func (s *Scanner) setErr(err error) { } } -// Buffer sets the initial buffer to use when scanning +// Buffer controls memory allocation by the Scanner. +// It sets the initial buffer to use when scanning // and the maximum size of buffer that may be allocated during scanning. +// The contents of the buffer are ignored. +// // The maximum token size must be less than the larger of max and cap(buf). // If max <= cap(buf), [Scanner.Scan] will use this buffer only and do no allocation. // diff --git a/src/bytes/buffer.go b/src/bytes/buffer.go index f90d9eca..96845139 100644 --- a/src/bytes/buffer.go +++ b/src/bytes/buffer.go @@ -21,6 +21,12 @@ type Buffer struct { buf []byte // contents are the bytes buf[off : len(buf)] off int // read at &buf[off], write at &buf[len(buf)] lastRead readOp // last read operation, so that Unread* can work correctly. + + // Copying and modifying a non-zero Buffer is prone to error, + // but we cannot employ the noCopy trick used by WaitGroup and Mutex, + // which causes vet's copylocks checker to report misuse, as vet + // cannot reliably distinguish the zero and non-zero cases. + // See #26462, #25907, #47276, #48398 for history. } // The readOp constants describe the last action performed on diff --git a/src/bytes/buffer_test.go b/src/bytes/buffer_test.go index 97fca5a9..b46ba120 100644 --- a/src/bytes/buffer_test.go +++ b/src/bytes/buffer_test.go @@ -354,7 +354,7 @@ func TestWriteAppend(t *testing.T) { got.Write(b) } if !Equal(got.Bytes(), want) { - t.Fatalf("Bytes() = %q, want %q", got, want) + t.Fatalf("Bytes() = %q, want %q", &got, want) } // With a sufficiently sized buffer, there should be no allocations. diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go index 4a2c9eac..a0a8fa0b 100644 --- a/src/bytes/bytes.go +++ b/src/bytes/bytes.go @@ -451,7 +451,9 @@ var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1} // Fields interprets s as a sequence of UTF-8-encoded code points. // It splits the slice s around each instance of one or more consecutive white space // characters, as defined by [unicode.IsSpace], returning a slice of subslices of s or an -// empty slice if s contains only white space. +// empty slice if s contains only white space. Every element of the returned slice is +// non-empty. Unlike [Split], leading and trailing runs of white space characters +// are discarded. func Fields(s []byte) [][]byte { // First count the fields. // This is an exact count if s is ASCII, otherwise it is an approximation. @@ -505,7 +507,9 @@ func Fields(s []byte) [][]byte { // FieldsFunc interprets s as a sequence of UTF-8-encoded code points. // It splits the slice s at each run of code points c satisfying f(c) and // returns a slice of subslices of s. If all code points in s satisfy f(c), or -// len(s) == 0, an empty slice is returned. +// len(s) == 0, an empty slice is returned. Every element of the returned slice is +// non-empty. Unlike [SplitFunc], leading and trailing runs of code points +// satisfying f(c) are discarded. // // FieldsFunc makes no guarantees about the order in which it calls f(c) // and assumes that f always returns the same value for a given c. @@ -1188,19 +1192,22 @@ func Replace(s, old, new []byte, n int) []byte { t := make([]byte, len(s)+n*(len(new)-len(old))) w := 0 start := 0 - for i := 0; i < n; i++ { - j := start - if len(old) == 0 { - if i > 0 { - _, wid := utf8.DecodeRune(s[start:]) - j += wid - } - } else { - j += Index(s[start:], old) + if len(old) > 0 { + for range n { + j := start + Index(s[start:], old) + w += copy(t[w:], s[start:j]) + w += copy(t[w:], new) + start = j + len(old) } - w += copy(t[w:], s[start:j]) + } else { // len(old) == 0 w += copy(t[w:], new) - start = j + len(old) + for range n - 1 { + _, wid := utf8.DecodeRune(s[start:]) + j := start + wid + w += copy(t[w:], s[start:j]) + w += copy(t[w:], new) + start = j + } } w += copy(t[w:], s[start:]) return t[0:w] @@ -1221,7 +1228,7 @@ func ReplaceAll(s, old, new []byte) []byte { func EqualFold(s, t []byte) bool { // ASCII fast path i := 0 - for ; i < len(s) && i < len(t); i++ { + for n := min(len(s), len(t)); i < n; i++ { sr := s[i] tr := t[i] if sr|tr >= utf8.RuneSelf { diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go index ead58171..0f6cf499 100644 --- a/src/bytes/bytes_test.go +++ b/src/bytes/bytes_test.go @@ -7,6 +7,7 @@ package bytes_test import ( . "bytes" "fmt" + "internal/asan" "internal/testenv" "iter" "math" @@ -1786,9 +1787,20 @@ var ReplaceTests = []ReplaceTest{ func TestReplace(t *testing.T) { for _, tt := range ReplaceTests { - in := append([]byte(tt.in), " "...) + var ( + in = []byte(tt.in) + old = []byte(tt.old) + new = []byte(tt.new) + ) + if !asan.Enabled { + allocs := testing.AllocsPerRun(10, func() { Replace(in, old, new, tt.n) }) + if allocs > 1 { + t.Errorf("Replace(%q, %q, %q, %d) allocates %.2f objects", tt.in, tt.old, tt.new, tt.n, allocs) + } + } + in = append(in, " "...) in = in[:len(tt.in)] - out := Replace(in, []byte(tt.old), []byte(tt.new), tt.n) + out := Replace(in, old, new, tt.n) if s := string(out); s != tt.out { t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out) } @@ -1796,7 +1808,7 @@ func TestReplace(t *testing.T) { t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n) } if tt.n == -1 { - out := ReplaceAll(in, []byte(tt.old), []byte(tt.new)) + out := ReplaceAll(in, old, new) if s := string(out); s != tt.out { t.Errorf("ReplaceAll(%q, %q, %q) = %q, want %q", tt.in, tt.old, tt.new, s, tt.out) } @@ -1804,6 +1816,69 @@ func TestReplace(t *testing.T) { } } +func FuzzReplace(f *testing.F) { + for _, tt := range ReplaceTests { + f.Add([]byte(tt.in), []byte(tt.old), []byte(tt.new), tt.n) + } + f.Fuzz(func(t *testing.T, in, old, new []byte, n int) { + differentImpl := func(in, old, new []byte, n int) []byte { + var out Buffer + if n < 0 { + n = math.MaxInt + } + for i := 0; i < len(in); { + if n == 0 { + out.Write(in[i:]) + break + } + if HasPrefix(in[i:], old) { + out.Write(new) + i += len(old) + n-- + if len(old) != 0 { + continue + } + if i == len(in) { + break + } + } + if len(old) == 0 { + _, length := utf8.DecodeRune(in[i:]) + out.Write(in[i : i+length]) + i += length + } else { + out.WriteByte(in[i]) + i++ + } + } + if len(old) == 0 && n != 0 { + out.Write(new) + } + return out.Bytes() + } + if simple, replace := differentImpl(in, old, new, n), Replace(in, old, new, n); !slices.Equal(simple, replace) { + t.Errorf("The two implementations do not match %q != %q for Replace(%q, %q, %q, %d)", simple, replace, in, old, new, n) + } + }) +} + +func BenchmarkReplace(b *testing.B) { + for _, tt := range ReplaceTests { + desc := fmt.Sprintf("%q %q %q %d", tt.in, tt.old, tt.new, tt.n) + var ( + in = []byte(tt.in) + old = []byte(tt.old) + new = []byte(tt.new) + ) + b.Run(desc, func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + Replace(in, old, new, tt.n) + } + }) + } +} + type TitleTest struct { in, out string } @@ -2053,8 +2128,9 @@ func TestContainsFunc(t *testing.T) { var makeFieldsInput = func() []byte { x := make([]byte, 1<<20) // Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space. + r := rand.New(rand.NewSource(99)) for i := range x { - switch rand.Intn(10) { + switch r.Intn(10) { case 0: x[i] = ' ' case 1: @@ -2073,8 +2149,9 @@ var makeFieldsInput = func() []byte { var makeFieldsInputASCII = func() []byte { x := make([]byte, 1<<20) // Input is ~10% space, rest ASCII non-space. + r := rand.New(rand.NewSource(99)) for i := range x { - if rand.Intn(10) == 0 { + if r.Intn(10) == 0 { x[i] = ' ' } else { x[i] = 'x' @@ -2171,8 +2248,9 @@ func makeBenchInputHard() []byte { "hello", "world", } x := make([]byte, 0, 1<<20) + r := rand.New(rand.NewSource(99)) for { - i := rand.Intn(len(tokens)) + i := r.Intn(len(tokens)) if len(x)+len(tokens[i]) >= 1<<20 { break } diff --git a/src/bytes/example_test.go b/src/bytes/example_test.go index c9086d39..c489b950 100644 --- a/src/bytes/example_test.go +++ b/src/bytes/example_test.go @@ -245,9 +245,9 @@ func ExampleCut() { } func ExampleCutPrefix() { - show := func(s, sep string) { - after, found := bytes.CutPrefix([]byte(s), []byte(sep)) - fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, sep, after, found) + show := func(s, prefix string) { + after, found := bytes.CutPrefix([]byte(s), []byte(prefix)) + fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, prefix, after, found) } show("Gopher", "Go") show("Gopher", "ph") @@ -257,9 +257,9 @@ func ExampleCutPrefix() { } func ExampleCutSuffix() { - show := func(s, sep string) { - before, found := bytes.CutSuffix([]byte(s), []byte(sep)) - fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, sep, before, found) + show := func(s, suffix string) { + before, found := bytes.CutSuffix([]byte(s), []byte(suffix)) + fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, suffix, before, found) } show("Gopher", "Go") show("Gopher", "er") @@ -628,3 +628,93 @@ func ExampleToUpperSpecial() { // Original : ahoj vývojári golang // ToUpper : AHOJ VÝVOJÁRİ GOLANG } + +func ExampleLines() { + text := []byte("Hello\nWorld\nGo Programming\n") + for line := range bytes.Lines(text) { + fmt.Printf("%q\n", line) + } + + // Output: + // "Hello\n" + // "World\n" + // "Go Programming\n" +} + +func ExampleSplitSeq() { + s := []byte("a,b,c,d") + for part := range bytes.SplitSeq(s, []byte(",")) { + fmt.Printf("%q\n", part) + } + + // Output: + // "a" + // "b" + // "c" + // "d" +} + +func ExampleSplitAfterSeq() { + s := []byte("a,b,c,d") + for part := range bytes.SplitAfterSeq(s, []byte(",")) { + fmt.Printf("%q\n", part) + } + + // Output: + // "a," + // "b," + // "c," + // "d" +} + +func ExampleFieldsSeq() { + text := []byte("The quick brown fox") + fmt.Println("Split byte slice into fields:") + for word := range bytes.FieldsSeq(text) { + fmt.Printf("%q\n", word) + } + + textWithSpaces := []byte(" lots of spaces ") + fmt.Println("\nSplit byte slice with multiple spaces:") + for word := range bytes.FieldsSeq(textWithSpaces) { + fmt.Printf("%q\n", word) + } + + // Output: + // Split byte slice into fields: + // "The" + // "quick" + // "brown" + // "fox" + // + // Split byte slice with multiple spaces: + // "lots" + // "of" + // "spaces" +} + +func ExampleFieldsFuncSeq() { + text := []byte("The quick brown fox") + fmt.Println("Split on whitespace(similar to FieldsSeq):") + for word := range bytes.FieldsFuncSeq(text, unicode.IsSpace) { + fmt.Printf("%q\n", word) + } + + mixedText := []byte("abc123def456ghi") + fmt.Println("\nSplit on digits:") + for word := range bytes.FieldsFuncSeq(mixedText, unicode.IsDigit) { + fmt.Printf("%q\n", word) + } + + // Output: + // Split on whitespace(similar to FieldsSeq): + // "The" + // "quick" + // "brown" + // "fox" + // + // Split on digits: + // "abc" + // "def" + // "ghi" +} diff --git a/src/bytes/iter.go b/src/bytes/iter.go index 799602d9..b2abb2c9 100644 --- a/src/bytes/iter.go +++ b/src/bytes/iter.go @@ -28,30 +28,23 @@ func Lines(s []byte) iter.Seq[[]byte] { return } } - return - } -} - -// explodeSeq returns an iterator over the runes in s. -func explodeSeq(s []byte) iter.Seq[[]byte] { - return func(yield func([]byte) bool) { - for len(s) > 0 { - _, size := utf8.DecodeRune(s) - if !yield(s[:size:size]) { - return - } - s = s[size:] - } } } // splitSeq is SplitSeq or SplitAfterSeq, configured by how many // bytes of sep to include in the results (none or all). func splitSeq(s, sep []byte, sepSave int) iter.Seq[[]byte] { - if len(sep) == 0 { - return explodeSeq(s) - } return func(yield func([]byte) bool) { + if len(sep) == 0 { + for len(s) > 0 { + _, size := utf8.DecodeRune(s) + if !yield(s[:size:size]) { + return + } + s = s[size:] + } + return + } for { i := Index(s, sep) if i < 0 { diff --git a/src/bytes/iter_test.go b/src/bytes/iter_test.go new file mode 100644 index 00000000..e37fdfb9 --- /dev/null +++ b/src/bytes/iter_test.go @@ -0,0 +1,56 @@ +// Copyright 2024 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 bytes_test + +import ( + . "bytes" + "testing" +) + +func BenchmarkSplitSeqEmptySeparator(b *testing.B) { + for range b.N { + for range SplitSeq(benchInputHard, nil) { + } + } +} + +func BenchmarkSplitSeqSingleByteSeparator(b *testing.B) { + sep := []byte("/") + for range b.N { + for range SplitSeq(benchInputHard, sep) { + } + } +} + +func BenchmarkSplitSeqMultiByteSeparator(b *testing.B) { + sep := []byte("hello") + for range b.N { + for range SplitSeq(benchInputHard, sep) { + } + } +} + +func BenchmarkSplitAfterSeqEmptySeparator(b *testing.B) { + for range b.N { + for range SplitAfterSeq(benchInputHard, nil) { + } + } +} + +func BenchmarkSplitAfterSeqSingleByteSeparator(b *testing.B) { + sep := []byte("/") + for range b.N { + for range SplitAfterSeq(benchInputHard, sep) { + } + } +} + +func BenchmarkSplitAfterSeqMultiByteSeparator(b *testing.B) { + sep := []byte("hello") + for range b.N { + for range SplitAfterSeq(benchInputHard, sep) { + } + } +} diff --git a/src/clean.bat b/src/clean.bat index 6688b41e..2e038063 100644 --- a/src/clean.bat +++ b/src/clean.bat @@ -6,27 +6,16 @@ setlocal -set GOBUILDFAIL=0 - -go tool dist env -w -p >env.bat -if errorlevel 1 goto fail +go tool dist env -w -p >env.bat || exit /b 1 call .\env.bat del env.bat echo. -if exist %GOTOOLDIR%\dist.exe goto distok -echo cannot find %GOTOOLDIR%\dist; nothing to clean -goto fail -:distok +if not exist %GOTOOLDIR%\dist.exe ( + echo cannot find %GOTOOLDIR%\dist.exe; nothing to clean + exit /b 1 +) "%GOBIN%\go" clean -i std "%GOBIN%\go" tool dist clean "%GOBIN%\go" clean -i cmd - -goto end - -:fail -set GOBUILDFAIL=1 - -:end -if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL% diff --git a/src/cmd/api/api_test.go b/src/cmd/api/api_test.go index 32da6898..98ebf168 100644 --- a/src/cmd/api/api_test.go +++ b/src/cmd/api/api_test.go @@ -99,6 +99,11 @@ func TestGolden(t *testing.T) { } func TestCompareAPI(t *testing.T) { + if *flagCheck { + // not worth repeating in -check + t.Skip("skipping with -check set") + } + tests := []struct { name string features, required, exception []string @@ -180,6 +185,11 @@ func TestCompareAPI(t *testing.T) { } func TestSkipInternal(t *testing.T) { + if *flagCheck { + // not worth repeating in -check + t.Skip("skipping with -check set") + } + tests := []struct { pkg string want bool @@ -294,14 +304,20 @@ func TestIssue41358(t *testing.T) { } func TestIssue64958(t *testing.T) { + if testing.Short() { + t.Skip("skipping with -short") + } + if *flagCheck { + // slow, not worth repeating in -check + t.Skip("skipping with -check set") + } + testenv.MustHaveGoBuild(t) + defer func() { if x := recover(); x != nil { t.Errorf("expected no panic; recovered %v", x) } }() - - testenv.MustHaveGoBuild(t) - for _, context := range contexts { w := NewWalker(context, "testdata/src/issue64958") pkg, err := w.importFrom("p", "", 0) diff --git a/src/cmd/api/main_test.go b/src/cmd/api/main_test.go index a0820c22..ed366be4 100644 --- a/src/cmd/api/main_test.go +++ b/src/cmd/api/main_test.go @@ -1058,7 +1058,7 @@ func (w *Walker) emitIfaceType(name string, typ *types.Interface) { if w.isDeprecated(m) { w.emitf("%s //deprecated", m.Name()) } - w.emitf("%s%s", m.Name(), w.signatureString(m.Type().(*types.Signature))) + w.emitf("%s%s", m.Name(), w.signatureString(m.Signature())) } if !complete { @@ -1088,7 +1088,7 @@ func (w *Walker) emitIfaceType(name string, typ *types.Interface) { } func (w *Walker) emitFunc(f *types.Func) { - sig := f.Type().(*types.Signature) + sig := f.Signature() if sig.Recv() != nil { panic("method considered a regular function: " + f.String()) } diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go index e63601de..87ccb8c0 100644 --- a/src/cmd/asm/internal/arch/arm64.go +++ b/src/cmd/asm/internal/arch/arm64.go @@ -59,10 +59,10 @@ func jumpArm64(word string) bool { var arm64SpecialOperand map[string]arm64.SpecialOperand -// GetARM64SpecialOperand returns the internal representation of a special operand. -func GetARM64SpecialOperand(name string) arm64.SpecialOperand { +// ARM64SpecialOperand returns the internal representation of a special operand. +func ARM64SpecialOperand(name string) arm64.SpecialOperand { if arm64SpecialOperand == nil { - // Generate the mapping automatically when the first time the function is called. + // Generate mapping when function is first called. arm64SpecialOperand = map[string]arm64.SpecialOperand{} for opd := arm64.SPOP_BEGIN; opd < arm64.SPOP_END; opd++ { arm64SpecialOperand[opd.String()] = opd diff --git a/src/cmd/asm/internal/arch/loong64.go b/src/cmd/asm/internal/arch/loong64.go index d9e428d9..bf5175f4 100644 --- a/src/cmd/asm/internal/arch/loong64.go +++ b/src/cmd/asm/internal/arch/loong64.go @@ -46,6 +46,14 @@ func IsLoong64RDTIME(op obj.As) bool { return false } +func IsLoong64PRELD(op obj.As) bool { + switch op { + case loong64.APRELD, loong64.APRELDX: + return true + } + return false +} + func IsLoong64AMO(op obj.As) bool { return loong64.IsAtomicInst(op) } diff --git a/src/cmd/asm/internal/arch/riscv64.go b/src/cmd/asm/internal/arch/riscv64.go index 27a66c5e..69e060a8 100644 --- a/src/cmd/asm/internal/arch/riscv64.go +++ b/src/cmd/asm/internal/arch/riscv64.go @@ -13,9 +13,8 @@ import ( "cmd/internal/obj/riscv" ) -// IsRISCV64AMO reports whether the op (as defined by a riscv.A* -// constant) is one of the AMO instructions that requires special -// handling. +// IsRISCV64AMO reports whether op is an AMO instruction that requires +// special handling. func IsRISCV64AMO(op obj.As) bool { switch op { case riscv.ASCW, riscv.ASCD, riscv.AAMOSWAPW, riscv.AAMOSWAPD, riscv.AAMOADDW, riscv.AAMOADDD, @@ -26,3 +25,33 @@ func IsRISCV64AMO(op obj.As) bool { } return false } + +// IsRISCV64VTypeI reports whether op is a vtype immediate instruction that +// requires special handling. +func IsRISCV64VTypeI(op obj.As) bool { + return op == riscv.AVSETVLI || op == riscv.AVSETIVLI +} + +var riscv64SpecialOperand map[string]riscv.SpecialOperand + +// RISCV64SpecialOperand returns the internal representation of a special operand. +func RISCV64SpecialOperand(name string) riscv.SpecialOperand { + if riscv64SpecialOperand == nil { + // Generate mapping when function is first called. + riscv64SpecialOperand = map[string]riscv.SpecialOperand{} + for opd := riscv.SPOP_BEGIN; opd < riscv.SPOP_END; opd++ { + riscv64SpecialOperand[opd.String()] = opd + } + } + if opd, ok := riscv64SpecialOperand[name]; ok { + return opd + } + return riscv.SPOP_END +} + +// RISCV64ValidateVectorType reports whether the given configuration is a +// valid vector type. +func RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask int64) error { + _, err := riscv.EncodeVectorType(vsew, vlmul, vtail, vmask) + return err +} diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 9fc7fa55..9a6e22ca 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -654,6 +654,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { prog.RegTo2 = a[1].Reg break } + + if arch.IsLoong64PRELD(op) { + prog.From = a[0] + prog.AddRestSource(a[1]) + break + } } prog.From = a[0] prog.To = a[1] @@ -670,6 +676,11 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { prog.From = a[0] prog.To = a[1] prog.RegTo2 = a[2].Reg + + case arch.IsLoong64PRELD(op): + prog.From = a[0] + prog.AddRestSourceArgs([]obj.Addr{a[1], a[2]}) + default: prog.From = a[0] prog.Reg = p.getRegister(prog, op, &a[1]) @@ -915,6 +926,19 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { prog.To = a[5] break } + if p.arch.Family == sys.RISCV64 && arch.IsRISCV64VTypeI(op) { + prog.From = a[0] + vsew := p.getSpecial(prog, op, &a[1]) + vlmul := p.getSpecial(prog, op, &a[2]) + vtail := p.getSpecial(prog, op, &a[3]) + vmask := p.getSpecial(prog, op, &a[4]) + if err := arch.RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask); err != nil { + p.errorf("invalid vtype: %v", err) + } + prog.AddRestSourceArgs([]obj.Addr{a[1], a[2], a[3], a[4]}) + prog.To = a[5] + break + } fallthrough default: p.errorf("can't handle %s instruction with %d operands", op, len(a)) @@ -965,3 +989,11 @@ func (p *Parser) getRegister(prog *obj.Prog, op obj.As, addr *obj.Addr) int16 { } return addr.Reg } + +// getSpecial checks that addr represents a special operand and returns its value. +func (p *Parser) getSpecial(prog *obj.Prog, op obj.As, addr *obj.Addr) int64 { + if addr.Type != obj.TYPE_SPECIAL || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 { + p.errorf("%s: expected special operand; found %s", op, obj.Dconv(prog, addr)) + } + return addr.Offset +} diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index 6e1aa1cd..afaf0281 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -465,9 +465,15 @@ func TestLOONG64Encoder(t *testing.T) { testEndToEnd(t, "loong64", "loong64enc1") testEndToEnd(t, "loong64", "loong64enc2") testEndToEnd(t, "loong64", "loong64enc3") + testEndToEnd(t, "loong64", "loong64enc4") + testEndToEnd(t, "loong64", "loong64enc5") testEndToEnd(t, "loong64", "loong64") } +func TestLOONG64Errors(t *testing.T) { + testErrors(t, "loong64", "loong64error") +} + func TestPPC64EndToEnd(t *testing.T) { defer func(old int) { buildcfg.GOPPC64 = old }(buildcfg.GOPPC64) for _, goppc64 := range []int{8, 9, 10} { @@ -487,6 +493,10 @@ func TestRISCVErrors(t *testing.T) { testErrors(t, "riscv64", "riscv64error") } +func TestRISCVValidation(t *testing.T) { + testErrors(t, "riscv64", "riscv64validation") +} + func TestS390XEndToEnd(t *testing.T) { testEndToEnd(t, "s390x", "s390x") } diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index 638f4e2f..8f8f6dcc 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -21,6 +21,7 @@ import ( "cmd/asm/internal/lex" "cmd/internal/obj" "cmd/internal/obj/arm64" + "cmd/internal/obj/riscv" "cmd/internal/obj/x86" "cmd/internal/objabi" "cmd/internal/src" @@ -398,16 +399,21 @@ func (p *Parser) operand(a *obj.Addr) { tok := p.next() name := tok.String() if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) { + // See if this is an architecture specific special operand. switch p.arch.Family { case sys.ARM64: - // arm64 special operands. - if opd := arch.GetARM64SpecialOperand(name); opd != arm64.SPOP_END { + if opd := arch.ARM64SpecialOperand(name); opd != arm64.SPOP_END { a.Type = obj.TYPE_SPECIAL a.Offset = int64(opd) - break } - fallthrough - default: + case sys.RISCV64: + if opd := arch.RISCV64SpecialOperand(name); opd != riscv.SPOP_END { + a.Type = obj.TYPE_SPECIAL + a.Offset = int64(opd) + } + } + + if a.Type != obj.TYPE_SPECIAL { // We have a symbol. Parse $sym±offset(symkind) p.symbolReference(a, p.qualifySymbol(name), prefix) } diff --git a/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s b/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s index 08cb20c7..197b2ce6 100644 --- a/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s +++ b/src/cmd/asm/internal/asm/testdata/amd64enc_extra.s @@ -1059,5 +1059,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 RDPID DX // f30fc7fa RDPID R11 // f3410fc7fb + ENDBR64 // f30f1efa + // End of tests. RET diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 14a1c914..236f1a66 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -1888,4 +1888,10 @@ next: DC CIGDVAC, R25 // b97e0bd5 DC CVAP, R26 // 3a7c0bd5 DC CVADP, R27 // 3b7d0bd5 + +// Branch Target Identification + BTI C // 5f2403d5 + BTI J // 9f2403d5 + BTI JC // df2403d5 + END diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 3ac87884..55890ce3 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -420,4 +420,6 @@ TEXT errors(SB),$0 AESE V1.B16, V2.B8 // ERROR "invalid arrangement" SHA256SU1 V1.S4, V2.B16, V3.S4 // ERROR "invalid arrangement" SHA1H V1.B16, V2.B16 // ERROR "invalid operands" + BTI // ERROR "missing operand" + BTI PLDL1KEEP // ERROR "illegal argument" RET diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s index 4a88aca0..bfff5557 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s @@ -6,12 +6,16 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 lable1: - BFPT 1(PC) // 00050048 - BFPT lable1 // BFPT 2 //1ffdff4b + BFPT 1(PC) // 00050048 + BFPT lable1 // BFPT 2 // 1ffdff4b + BFPT FCC0, lable1 // BFPT FCC0, 2 // 1ff9ff4b + BFPT FCC7, lable1 // BFPT FCC7, 2 // fff5ff4b lable2: - BFPF 1(PC) // 00040048 - BFPF lable2 // BFPF 4 // 1ffcff4b + BFPF 1(PC) // 00040048 + BFPF lable2 // BFPF 6 // 1ffcff4b + BFPF FCC0, lable2 // BFPF FCC0, 6 // 1ff8ff4b + BFPF FCC7, lable2 // BFPF FCC7, 6 // fff4ff4b // relocation in play so the assembled offset should be 0 JMP foo(SB) // 00000050 @@ -107,8 +111,8 @@ lable2: MOVV $4(R4), R5 // 8510c002 MOVW $-1, R4 // 04fcff02 MOVV $-1, R4 // 04fcff02 - MOVW $1, R4 // 0404c002 - MOVV $1, R4 // 0404c002 + MOVW $1, R4 // 04048003 + MOVV $1, R4 // 04048003 ADD $-1, R4, R5 // 85fcbf02 ADD $-1, R4 // 84fcbf02 ADDV $-1, R4, R5 // 85fcff02 @@ -346,6 +350,15 @@ lable2: FTINTVF F0, F1 // 01241b01 FTINTVD F0, F1 // 01281b01 + FMAXAF F4, F5, F6 // a6900c01 + FMAXAF F4, F5 // a5900c01 + FMAXAD F4, F5, F6 // a6100d01 + FMAXAD F4, F5 // a5100d01 + FMINAF F4, F5, F6 // a6900e01 + FMINAF F4, F5 // a5900e01 + FMINAD F4, F5, F6 // a6100f01 + FMINAD F4, F5 // a5100f01 + FTINTRMWF F0, F2 // 02041a01 FTINTRMWD F0, F2 // 02081a01 FTINTRMVF F0, F2 // 02241a01 @@ -506,6 +519,16 @@ lable2: XVSEQH X3, X2, X4 // 448c0074 XVSEQW X3, X2, X4 // 440c0174 XVSEQV X3, X2, X4 // 448c0174 + VSEQB $0, V2, V3 // 43008072 + VSEQH $1, V2, V3 // 43848072 + VSEQW $8, V2, V3 // 43208172 + VSEQV $15, V2, V3 // 43bc8172 + VSEQV $-15, V2, V3 // 43c48172 + XVSEQB $0, X2, X4 // 44008076 + XVSEQH $3, X2, X4 // 448c8076 + XVSEQW $12, X2, X4 // 44308176 + XVSEQV $15, X2, X4 // 44bc8176 + XVSEQV $-15, X2, X4 // 44c48176 // VPCNT{B,H,W,V}, XVPCNT{B,H,W,V} instruction VPCNTB V1, V2 // 22209c72 @@ -516,3 +539,499 @@ lable2: XVPCNTH X3, X2 // 62249c76 XVPCNTW X3, X2 // 62289c76 XVPCNTV X3, X2 // 622c9c76 + + // VANDV,VORV,VXORV,VNORV,VANDNV,VORNV + VANDV V1, V2, V3 // 43042671 + VORV V1, V2, V3 // 43842671 + VXORV V1, V2, V3 // 43042771 + VNORV V1, V2, V3 // 43842771 + VANDNV V1, V2, V3 // 43042871 + VORNV V1, V2, V3 // 43842871 + VANDV V1, V2 // 42042671 + VORV V1, V2 // 42842671 + VXORV V1, V2 // 42042771 + VNORV V1, V2 // 42842771 + VANDNV V1, V2 // 42042871 + VORNV V1, V2 // 42842871 + + // VANDB,VORB,VXORB,VNORB + VANDB $0, V2, V3 // 4300d073 + VORB $64, V2, V3 // 4300d573 + VXORB $128, V2, V3 // 4300da73 + VNORB $255, V2, V3 // 43fcdf73 + VANDB $0, V2 // 4200d073 + VORB $64, V2 // 4200d573 + VXORB $128, V2 // 4200da73 + VNORB $255, V2 // 42fcdf73 + + // XVANDV,XVORV,XVXORV,XVNORV,XVANDNV,XVORNV + XVANDV X1, X2, X3 // 43042675 + XVORV X1, X2, X3 // 43842675 + XVXORV X1, X2, X3 // 43042775 + XVNORV X1, X2, X3 // 43842775 + XVANDNV X1, X2, X3 // 43042875 + XVORNV X1, X2, X3 // 43842875 + XVANDV X1, X2 // 42042675 + XVORV X1, X2 // 42842675 + XVXORV X1, X2 // 42042775 + XVNORV X1, X2 // 42842775 + XVANDNV X1, X2 // 42042875 + XVORNV X1, X2 // 42842875 + + // XVANDB,XVORB,XVXORB,XVNORB + XVANDB $0, X2, X3 // 4300d077 + XVORB $1, X2, X3 // 4304d477 + XVXORB $127, X2, X3 // 43fcd977 + XVNORB $255, X2, X3 // 43fcdf77 + XVANDB $0, X2 // 4200d077 + XVORB $1, X2 // 4204d477 + XVXORB $127, X2 // 42fcd977 + XVNORB $255, X2 // 42fcdf77 + + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 + + // MOVV C_UCON, r + MOVV $0x54321000, R4 // MOVV $1412567040, R4 // 2464a814 + MOVV $0xffffffff8432f000, R4 // MOVV $-2077036544, R4 // e4650815 + + // MOVV C_ADDCON, r + MOVV $0xfffffffffffff821, R4 // MOVV $-2015, R4 // 0484e002 + + // MOVV C_ANDCON, r + MOVV $0x821, R4 // MOVV $2081, R4 // 0484a003 + + // ADDV C_SCON, [r1], r2 + ADDV $0x321, R4 // ADDV $801, R4 // 8484cc02 + ADDV $0x321, R5, R4 // ADDV $801, R5, R4 // a484cc02 + ADDV $0xfffffffffffffc21, R4 // ADDV $-991, R4 // 8484f002 + ADDV $0xfffffffffffffc21, R5, R4 // ADDV $-991, R5, R4 // a484f002 + + // AND C_SCON, [r1], r2 + AND $0x321, R4 // AND $801, R4 // 84844c03 + AND $0x321, R5, R4 // AND $801, R5, R4 // a4844c03 + + // [X]{VSLL/VSRL/VSRA/VROTR}{B,H,W,V} instructions + VSLLB V1, V2, V3 // 4304e870 + VSLLH V1, V2, V3 // 4384e870 + VSLLW V1, V2, V3 // 4304e970 + VSLLV V1, V2, V3 // 4384e970 + VSRLB V1, V2, V3 // 4304ea70 + VSRLH V1, V2, V3 // 4384ea70 + VSRLW V1, V2, V3 // 4304eb70 + VSRLV V1, V2, V3 // 4384eb70 + VSRAB V1, V2, V3 // 4304ec70 + VSRAH V1, V2, V3 // 4384ec70 + VSRAW V1, V2, V3 // 4304ed70 + VSRAV V1, V2, V3 // 4384ed70 + VROTRB V1, V2, V3 // 4304ee70 + VROTRH V1, V2, V3 // 4384ee70 + VROTRW V1, V2, V3 // 4304ef70 + VROTRV V1, V2, V3 // 4384ef70 + XVSLLB X3, X2, X1 // 410ce874 + XVSLLH X3, X2, X1 // 418ce874 + XVSLLW X3, X2, X1 // 410ce974 + XVSLLV X3, X2, X1 // 418ce974 + XVSRLB X3, X2, X1 // 410cea74 + XVSRLH X3, X2, X1 // 418cea74 + XVSRLW X3, X2, X1 // 410ceb74 + XVSRLV X3, X2, X1 // 418ceb74 + XVSRAB X3, X2, X1 // 410cec74 + XVSRAH X3, X2, X1 // 418cec74 + XVSRAW X3, X2, X1 // 410ced74 + XVSRAV X3, X2, X1 // 418ced74 + XVROTRB X3, X2, X1 // 410cee74 + XVROTRH X3, X2, X1 // 418cee74 + XVROTRW X3, X2, X1 // 410cef74 + XVROTRV X3, X2, X1 // 418cef74 + VSLLB $0, V1, V2 // 22202c73 + VSLLB $7, V1, V2 // 223c2c73 + VSLLB $5, V1 // 21342c73 + VSLLH $0, V1, V2 // 22402c73 + VSLLH $15, V1, V2 // 227c2c73 + VSLLH $10, V1 // 21682c73 + VSLLW $0, V1, V2 // 22802c73 + VSLLW $31, V1, V2 // 22fc2c73 + VSLLW $11, V1 // 21ac2c73 + VSLLV $0, V1, V2 // 22002d73 + VSLLV $63, V1, V2 // 22fc2d73 + VSLLV $30, V1 // 21782d73 + VSRLB $0, V1, V2 // 22203073 + VSRLB $7, V1, V2 // 223c3073 + VSRLB $4, V1 // 21303073 + VSRLH $0, V1, V2 // 22403073 + VSRLH $15, V1, V2 // 227c3073 + VSRLH $9, V1 // 21643073 + VSRLW $0, V1, V2 // 22803073 + VSRLW $31, V1, V2 // 22fc3073 + VSRLW $16, V1 // 21c03073 + VSRLV $0, V1, V2 // 22003173 + VSRLV $63, V1, V2 // 22fc3173 + VSRLV $40, V1 // 21a03173 + VSRAB $0, V1, V2 // 22203473 + VSRAB $7, V1, V2 // 223c3473 + VSRAB $6, V1 // 21383473 + VSRAH $0, V1, V2 // 22403473 + VSRAH $15, V1, V2 // 227c3473 + VSRAH $8, V1 // 21603473 + VSRAW $0, V1, V2 // 22803473 + VSRAW $31, V1, V2 // 22fc3473 + VSRAW $12, V1 // 21b03473 + VSRAV $0, V1, V2 // 22003573 + VSRAV $63, V1, V2 // 22fc3573 + VSRAV $50, V1 // 21c83573 + VROTRB $0, V1, V2 // 2220a072 + VROTRB $7, V1, V2 // 223ca072 + VROTRB $3, V1 // 212ca072 + VROTRH $0, V1, V2 // 2240a072 + VROTRH $15, V1, V2 // 227ca072 + VROTRH $5, V1 // 2154a072 + VROTRW $0, V1, V2 // 2280a072 + VROTRW $31, V1, V2 // 22fca072 + VROTRW $18, V1 // 21c8a072 + VROTRV $0, V1, V2 // 2200a172 + VROTRV $63, V1, V2 // 22fca172 + VROTRV $52, V1 // 21d0a172 + XVSLLB $0, X2, X1 // 41202c77 + XVSLLB $7, X2, X1 // 413c2c77 + XVSLLB $4, X2 // 42302c77 + XVSLLH $0, X2, X1 // 41402c77 + XVSLLH $15, X2, X1 // 417c2c77 + XVSLLH $8, X2 // 42602c77 + XVSLLW $0, X2, X1 // 41802c77 + XVSLLW $31, X2, X1 // 41fc2c77 + XVSLLW $13, X2 // 42b42c77 + XVSLLV $0, X2, X1 // 41002d77 + XVSLLV $63, X2, X1 // 41fc2d77 + XVSLLV $36, X2 // 42902d77 + XVSRLB $0, X2, X1 // 41203077 + XVSRLB $7, X2, X1 // 413c3077 + XVSRLB $5, X2 // 42343077 + XVSRLH $0, X2, X1 // 41403077 + XVSRLH $15, X2, X1 // 417c3077 + XVSRLH $9, X2 // 42643077 + XVSRLW $0, X2, X1 // 41803077 + XVSRLW $31, X2, X1 // 41fc3077 + XVSRLW $14, X2 // 42b83077 + XVSRLV $0, X2, X1 // 41003177 + XVSRLV $63, X2, X1 // 41fc3177 + XVSRLV $45, X2 // 42b43177 + XVSRAB $0, X2, X1 // 41203477 + XVSRAB $7, X2, X1 // 413c3477 + XVSRAB $6, X2 // 42383477 + XVSRAH $0, X2, X1 // 41403477 + XVSRAH $15, X2, X1 // 417c3477 + XVSRAH $10, X2 // 42683477 + XVSRAW $0, X2, X1 // 41803477 + XVSRAW $31, X2, X1 // 41fc3477 + XVSRAW $16, X2 // 42c03477 + XVSRAV $0, X2, X1 // 41003577 + XVSRAV $63, X2, X1 // 41fc3577 + XVSRAV $48, X2 // 42c03577 + XVROTRB $0, X2, X1 // 4120a076 + XVROTRB $7, X2, X1 // 413ca076 + XVROTRB $3, X2 // 422ca076 + XVROTRH $0, X2, X1 // 4140a076 + XVROTRH $15, X2, X1 // 417ca076 + XVROTRH $13, X2 // 4274a076 + XVROTRW $0, X2, X1 // 4180a076 + XVROTRW $31, X2, X1 // 41fca076 + XVROTRW $24, X2 // 42e0a076 + XVROTRV $0, X2, X1 // 4100a176 + XVROTRV $63, X2, X1 // 41fca176 + XVROTRV $52, X2 // 42d0a176 + + // [X]VADD{B,H,W,V,Q}, [X]VSUB{B,H,W,V,Q} instructions + VADDB V1, V2, V3 // 43040a70 + VADDH V1, V2, V3 // 43840a70 + VADDW V1, V2, V3 // 43040b70 + VADDV V1, V2, V3 // 43840b70 + VADDQ V1, V2, V3 // 43042d71 + VSUBB V1, V2, V3 // 43040c70 + VSUBH V1, V2, V3 // 43840c70 + VSUBW V1, V2, V3 // 43040d70 + VSUBV V1, V2, V3 // 43840d70 + VSUBQ V1, V2, V3 // 43842d71 + XVADDB X3, X2, X1 // 410c0a74 + XVADDH X3, X2, X1 // 418c0a74 + XVADDW X3, X2, X1 // 410c0b74 + XVADDV X3, X2, X1 // 418c0b74 + XVADDQ X3, X2, X1 // 410c2d75 + XVSUBB X3, X2, X1 // 410c0c74 + XVSUBH X3, X2, X1 // 418c0c74 + XVSUBW X3, X2, X1 // 410c0d74 + XVSUBV X3, X2, X1 // 418c0d74 + XVSUBQ X3, X2, X1 // 418c2d75 + + // [X]VADD{B,H,W,V}U, [X]VSUB{B,H,W,V}U instructions + VADDBU $1, V2, V1 // 41048a72 + VADDHU $2, V2, V1 // 41888a72 + VADDWU $3, V2, V1 // 410c8b72 + VADDVU $4, V2, V1 // 41908b72 + VSUBBU $5, V2, V1 // 41148c72 + VSUBHU $6, V2, V1 // 41988c72 + VSUBWU $7, V2, V1 // 411c8d72 + VSUBVU $8, V2, V1 // 41a08d72 + XVADDBU $9, X1, X2 // 22248a76 + XVADDHU $10, X1, X2 // 22a88a76 + XVADDWU $11, X1, X2 // 222c8b76 + XVADDVU $12, X1, X2 // 22b08b76 + XVSUBBU $13, X1, X2 // 22348c76 + XVSUBHU $14, X1, X2 // 22b88c76 + XVSUBWU $15, X1, X2 // 223c8d76 + XVSUBVU $16, X1, X2 // 22c08d76 + + // [X]VILV{L/H}{B,H,W,V} instructions + VILVLB V1, V2, V3 // 43041a71 + VILVLH V1, V2, V3 // 43841a71 + VILVLW V1, V2, V3 // 43041b71 + VILVLV V1, V2, V3 // 43841b71 + VILVHB V1, V2, V3 // 43041c71 + VILVHH V1, V2, V3 // 43841c71 + VILVHW V1, V2, V3 // 43041d71 + VILVHV V1, V2, V3 // 43841d71 + XVILVLB X3, X2, X1 // 410c1a75 + XVILVLH X3, X2, X1 // 418c1a75 + XVILVLW X3, X2, X1 // 410c1b75 + XVILVLV X3, X2, X1 // 418c1b75 + XVILVHB X3, X2, X1 // 410c1c75 + XVILVHH X3, X2, X1 // 418c1c75 + XVILVHW X3, X2, X1 // 410c1d75 + XVILVHV X3, X2, X1 // 418c1d75 + + // [X]VMUL{B/H/W/V} and [X]VMUH{B/H/W/V}[U] instructions + VMULB V1, V2, V3 // 43048470 + VMULH V1, V2, V3 // 43848470 + VMULW V1, V2, V3 // 43048570 + VMULV V1, V2, V3 // 43848570 + VMUHB V1, V2, V3 // 43048670 + VMUHH V1, V2, V3 // 43848670 + VMUHW V1, V2, V3 // 43048770 + VMUHV V1, V2, V3 // 43848770 + VMUHBU V1, V2, V3 // 43048870 + VMUHHU V1, V2, V3 // 43848870 + VMUHWU V1, V2, V3 // 43048970 + VMUHVU V1, V2, V3 // 43848970 + XVMULB X3, X2, X1 // 410c8474 + XVMULH X3, X2, X1 // 418c8474 + XVMULW X3, X2, X1 // 410c8574 + XVMULV X3, X2, X1 // 418c8574 + XVMUHB X3, X2, X1 // 410c8674 + XVMUHH X3, X2, X1 // 418c8674 + XVMUHW X3, X2, X1 // 410c8774 + XVMUHV X3, X2, X1 // 418c8774 + XVMUHBU X3, X2, X1 // 410c8874 + XVMUHHU X3, X2, X1 // 418c8874 + XVMUHWU X3, X2, X1 // 410c8974 + XVMUHVU X3, X2, X1 // 418c8974 + + // [X]VDIV{B/H/W/V}[U] and [X]VMOD{B/H/W/V}[U] instructions + VDIVB V1, V2, V3 // 4304e070 + VDIVH V1, V2, V3 // 4384e070 + VDIVW V1, V2, V3 // 4304e170 + VDIVV V1, V2, V3 // 4384e170 + VDIVBU V1, V2, V3 // 4304e470 + VDIVHU V1, V2, V3 // 4384e470 + VDIVWU V1, V2, V3 // 4304e570 + VDIVVU V1, V2, V3 // 4384e570 + VMODB V1, V2, V3 // 4304e270 + VMODH V1, V2, V3 // 4384e270 + VMODW V1, V2, V3 // 4304e370 + VMODV V1, V2, V3 // 4384e370 + VMODBU V1, V2, V3 // 4304e670 + VMODHU V1, V2, V3 // 4384e670 + VMODWU V1, V2, V3 // 4304e770 + VMODVU V1, V2, V3 // 4384e770 + XVDIVB X3, X2, X1 // 410ce074 + XVDIVH X3, X2, X1 // 418ce074 + XVDIVW X3, X2, X1 // 410ce174 + XVDIVV X3, X2, X1 // 418ce174 + XVDIVBU X3, X2, X1 // 410ce474 + XVDIVHU X3, X2, X1 // 418ce474 + XVDIVWU X3, X2, X1 // 410ce574 + XVDIVVU X3, X2, X1 // 418ce574 + XVMODB X3, X2, X1 // 410ce274 + XVMODH X3, X2, X1 // 418ce274 + XVMODW X3, X2, X1 // 410ce374 + XVMODV X3, X2, X1 // 418ce374 + XVMODBU X3, X2, X1 // 410ce674 + XVMODHU X3, X2, X1 // 418ce674 + XVMODWU X3, X2, X1 // 410ce774 + XVMODVU X3, X2, X1 // 418ce774 + + // [X]VF{SQRT/RECIP/RSQRT}{F/D} instructions + VFSQRTF V1, V2 // 22e49c72 + VFSQRTD V1, V2 // 22e89c72 + VFRECIPF V1, V2 // 22f49c72 + VFRECIPD V1, V2 // 22f89c72 + VFRSQRTF V1, V2 // 22049d72 + VFRSQRTD V1, V2 // 22089d72 + XVFSQRTF X2, X1 // 41e49c76 + XVFSQRTD X2, X1 // 41e89c76 + XVFRECIPF X2, X1 // 41f49c76 + XVFRECIPD X2, X1 // 41f89c76 + XVFRSQRTF X2, X1 // 41049d76 + XVFRSQRTD X2, X1 // 41089d76 + + // [X]VNEG{B/H/W/V} instructions + VNEGB V1, V2 // 22309c72 + VNEGH V1, V2 // 22349c72 + VNEGW V1, V2 // 22389c72 + VNEGV V1, V2 // 223c9c72 + XVNEGB X2, X1 // 41309c76 + XVNEGH X2, X1 // 41349c76 + XVNEGW X2, X1 // 41389c76 + XVNEGV X2, X1 // 413c9c76 + + // [X]{VMULW}{EV/OD}.{H.B/W.H/D.W/Q.D}[U] instructions + VMULWEVHB V1, V2, V3 // 43049070 + VMULWEVWH V1, V2, V3 // 43849070 + VMULWEVVW V1, V2, V3 // 43049170 + VMULWEVQV V1, V2, V3 // 43849170 + VMULWODHB V1, V2, V3 // 43049270 + VMULWODWH V1, V2, V3 // 43849270 + VMULWODVW V1, V2, V3 // 43049370 + VMULWODQV V1, V2, V3 // 43849370 + VMULWEVHBU V1, V2, V3 // 43049870 + VMULWEVWHU V1, V2, V3 // 43849870 + VMULWEVVWU V1, V2, V3 // 43049970 + VMULWEVQVU V1, V2, V3 // 43849970 + VMULWODHBU V1, V2, V3 // 43049a70 + VMULWODWHU V1, V2, V3 // 43849a70 + VMULWODVWU V1, V2, V3 // 43049b70 + VMULWODQVU V1, V2, V3 // 43849b70 + XVMULWEVHB X1, X2, X3 // 43049074 + XVMULWEVWH X1, X2, X3 // 43849074 + XVMULWEVVW X1, X2, X3 // 43049174 + XVMULWEVQV X1, X2, X3 // 43849174 + XVMULWODHB X1, X2, X3 // 43049274 + XVMULWODWH X1, X2, X3 // 43849274 + XVMULWODVW X1, X2, X3 // 43049374 + XVMULWODQV X1, X2, X3 // 43849374 + XVMULWEVHBU X1, X2, X3 // 43049874 + XVMULWEVWHU X1, X2, X3 // 43849874 + XVMULWEVVWU X1, X2, X3 // 43049974 + XVMULWEVQVU X1, X2, X3 // 43849974 + XVMULWODHBU X1, X2, X3 // 43049a74 + XVMULWODWHU X1, X2, X3 // 43849a74 + XVMULWODVWU X1, X2, X3 // 43049b74 + XVMULWODQVU X1, X2, X3 // 43849b74 + + // [X]{VMULW}{EV/OD}.{H.BU.B/W.HU.H/D.WU.W/Q.DU.D} instructions + VMULWEVHBUB V1, V2, V3 // 4304a070 + VMULWEVWHUH V1, V2, V3 // 4384a070 + VMULWEVVWUW V1, V2, V3 // 4304a170 + VMULWEVQVUV V1, V2, V3 // 4384a170 + VMULWODHBUB V1, V2, V3 // 4304a270 + VMULWODWHUH V1, V2, V3 // 4384a270 + VMULWODVWUW V1, V2, V3 // 4304a370 + VMULWODQVUV V1, V2, V3 // 4384a370 + XVMULWEVHBUB X1, X2, X3 // 4304a074 + XVMULWEVWHUH X1, X2, X3 // 4384a074 + XVMULWEVVWUW X1, X2, X3 // 4304a174 + XVMULWEVQVUV X1, X2, X3 // 4384a174 + XVMULWODHBUB X1, X2, X3 // 4304a274 + XVMULWODWHUH X1, X2, X3 // 4384a274 + XVMULWODVWUW X1, X2, X3 // 4304a374 + XVMULWODQVUV X1, X2, X3 // 4384a374 + + // [X]VSHUF4I.{B/H/W/D} instructions + VSHUF4IB $0, V2, V1 // 41009073 + VSHUF4IB $16, V2, V1 // 41409073 + VSHUF4IB $255, V2, V1 // 41fc9373 + VSHUF4IH $0, V2, V1 // 41009473 + VSHUF4IH $128, V2, V1 // 41009673 + VSHUF4IH $255, V2, V1 // 41fc9773 + VSHUF4IW $0, V2, V1 // 41009873 + VSHUF4IW $96, V2, V1 // 41809973 + VSHUF4IW $255, V2, V1 // 41fc9b73 + VSHUF4IV $0, V2, V1 // 41009c73 + VSHUF4IV $8, V2, V1 // 41209c73 + VSHUF4IV $15, V2, V1 // 413c9c73 + XVSHUF4IB $0, X1, X2 // 22009077 + XVSHUF4IB $16, X1, X2 // 22409077 + XVSHUF4IB $255, X1, X2 // 22fc9377 + XVSHUF4IH $0, X1, X2 // 22009477 + XVSHUF4IH $128, X1, X2 // 22009677 + XVSHUF4IH $255, X1, X2 // 22fc9777 + XVSHUF4IW $0, X1, X2 // 22009877 + XVSHUF4IW $96, X1, X2 // 22809977 + XVSHUF4IW $255, X1, X2 // 22fc9b77 + XVSHUF4IV $0, X1, X2 // 22009c77 + XVSHUF4IV $8, X1, X2 // 22209c77 + XVSHUF4IV $15, X1, X2 // 223c9c77 + + // [X]VSETEQZ.V, [X]VSETNEZ.V + VSETEQV V1, FCC0 // 20989c72 + VSETNEV V1, FCC0 // 209c9c72 + XVSETEQV X1, FCC0 // 20989c76 + XVSETNEV X1, FCC0 // 209c9c76 + // [X]VSETANYEQZ.{B/H/W/D} instructions + VSETANYEQB V1, FCC0 // 20a09c72 + VSETANYEQH V1, FCC0 // 20a49c72 + VSETANYEQW V1, FCC0 // 20a89c72 + VSETANYEQV V1, FCC0 // 20ac9c72 + VSETALLNEB V1, FCC0 // 20b09c72 + VSETALLNEH V1, FCC0 // 20b49c72 + VSETALLNEW V1, FCC0 // 20b89c72 + VSETALLNEV V1, FCC0 // 20bc9c72 + XVSETANYEQB X1, FCC0 // 20a09c76 + XVSETANYEQH X1, FCC0 // 20a49c76 + XVSETANYEQW X1, FCC0 // 20a89c76 + XVSETANYEQV X1, FCC0 // 20ac9c76 + XVSETALLNEB X1, FCC0 // 20b09c76 + XVSETALLNEH X1, FCC0 // 20b49c76 + XVSETALLNEW X1, FCC0 // 20b89c76 + XVSETALLNEV X1, FCC0 // 20bc9c76 + + // [X]VFRINT[{RNE/RZ/RP/RM}].{S/D} instructions + VFRINTRNEF V1, V2 // 22749d72 + VFRINTRNED V1, V2 // 22789d72 + VFRINTRZF V1, V2 // 22649d72 + VFRINTRZD V1, V2 // 22689d72 + VFRINTRPF V1, V2 // 22549d72 + VFRINTRPD V1, V2 // 22589d72 + VFRINTRMF V1, V2 // 22449d72 + VFRINTRMD V1, V2 // 22489d72 + VFRINTF V1, V2 // 22349d72 + VFRINTD V1, V2 // 22389d72 + XVFRINTRNEF X1, X2 // 22749d76 + XVFRINTRNED X1, X2 // 22789d76 + XVFRINTRZF X1, X2 // 22649d76 + XVFRINTRZD X1, X2 // 22689d76 + XVFRINTRPF X1, X2 // 22549d76 + XVFRINTRPD X1, X2 // 22589d76 + XVFRINTRMF X1, X2 // 22449d76 + XVFRINTRMD X1, X2 // 22489d76 + XVFRINTF X1, X2 // 22349d76 + XVFRINTD X1, X2 // 22389d76 + + // [X]VF{ADD/SUB/MUL/DIV}.{S/D} instructions + VADDF V1, V2, V3 // 43843071 + VADDD V1, V2, V3 // 43043171 + VSUBF V1, V2, V3 // 43843271 + VSUBD V1, V2, V3 // 43043371 + VMULF V1, V2, V3 // 43843871 + VMULD V1, V2, V3 // 43043971 + VDIVF V1, V2, V3 // 43843a71 + VDIVD V1, V2, V3 // 43043b71 + XVADDF X1, X2, X3 // 43843075 + XVADDD X1, X2, X3 // 43043175 + XVSUBF X1, X2, X3 // 43843275 + XVSUBD X1, X2, X3 // 43043375 + XVMULF X1, X2, X3 // 43843875 + XVMULD X1, X2, X3 // 43043975 + XVDIVF X1, X2, X3 // 43843a75 + XVDIVD X1, X2, X3 // 43043b75 + + // [X]VFCLASS.{S/D} instructions + VFCLASSF V1, V2 // 22d49c72 + VFCLASSD V1, V2 // 22d89c72 + XVFCLASSF X1, X2 // 22d49c76 + XVFCLASSD X1, X2 // 22d89c76 + + // PRELD{,X} instructions + PRELD (R4), $0 // 8000c02a + PRELD -1(R4), $8 // 88fcff2a + PRELD 8(R4), $31 // 9f20c02a diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc2.s b/src/cmd/asm/internal/asm/testdata/loong64enc2.s index e497b836..91aed4e2 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc2.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc2.s @@ -12,7 +12,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 AND $-1, R4, R5 // 1efcbf0285f81400 AND $-1, R4 // 1efcbf0284f81400 MOVW $-1, F4 // 1efcbf02c4a71401 - MOVW $1, F4 // 1e048002c4a71401 + MOVW $1, F4 // 1e048003c4a71401 TEQ $4, R4, R5 // 8508005c04002a00 TEQ $4, R4 // 0408005c04002a00 TNE $4, R4, R5 // 8508005804002a00 @@ -77,3 +77,49 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 MOVH name(SB), R4 // 1e00001ac4034028 MOVHU R4, name(SB) // 1e00001ac4034029 MOVHU name(SB), R4 // 1e00001ac403402a + + // MOVV C_DCON12_20S, r + MOVV $0x273fffff80000000, R4 // MOVV $2828260563841187840, R4 // 0400001584cc0903 + MOVV $0xf73fffff80000000, R4 // MOVV $-630503949979353088, R4 // 0400001584cc3d03 + + // MOVV C_DCON20S_20, r + MOVV $0xfff800000f000000, R4 // MOVV $-2251799562027008, R4 // 04001e1404000017 + + // MOVV C_DCON12_12S, r + MOVV $0x273ffffffffff800, R4 // MOVV $2828260565988669440, R4 // 0400e00284cc0903 + MOVV $0xf73ffffffffff800, R4 // MOVV $-630503947831871488, R4 // 0400e00284cc3d03 + + // MOVV C_DCON20S_12S, r + MOVV $0xfff80000fffff800, R4 // MOVV $-2251795518720000, R4 // 0400a00204000017 + MOVV $0xfff8000000000000, R4 // MOVV $-2251799813685248, R4 // 0400800204000017 + + // MOVV C_DCON12_12U, r + MOVV $0x2730000000000800, R4 // MOVV $2823756966361303040, R4 // 0400a00384cc0903 + MOVV $0xf730000000000800, R4 // MOVV $-635007547459237888, R4 // 0400a00384cc3d03 + + // MOVV C_DCON20S_12U, r + MOVV $0xfff8000000000800, R4 // MOVV $-2251799813683200, R4 // 0400a00304000017 + + // ADDV/AND C_DCON12_0, [r1], r2 + ADDV $0x3210000000000000, R4 // ADDV $3607383301523767296, R4 // 1e840c0384f81000 + ADDV $0x3210000000000000, R5, R4 // ADDV $3607383301523767296, R5, R4 // 1e840c03a4f81000 + ADDV $0xc210000000000000, R4 // ADDV $-4463067230724161536, R4 // 1e84300384f81000 + ADDV $0xc210000000000000, R5, R4 // ADDV $-4463067230724161536, R5, R4 // 1e843003a4f81000 + AND $0x3210000000000000, R4 // AND $3607383301523767296, R4 // 1e840c0384f81400 + AND $0x3210000000000000, R5, R4 // AND $3607383301523767296, R5, R4 // 1e840c03a4f81400 + AND $0xc210000000000000, R4 // AND $-4463067230724161536, R4 // 1e84300384f81400 + AND $0xc210000000000000, R5, R4 // AND $-4463067230724161536, R5, R4 // 1e843003a4f81400 + + // ADDV/AND C_UCON, [r1], r2 + ADDV $0x43210000, R4 // ADDV $1126236160, R4 // 1e42861484f81000 + ADDV $0x43210000, R5, R4 // ADDV $1126236160, R5, R4 // 1e428614a4f81000 + ADDV $0xffffffffc3210000, R4 // ADDV $-1021247488, R4 // 1e42861584f81000 + ADDV $0xffffffffc3210000, R5, R4 // ADDV $-1021247488, R5, R4 // 1e428615a4f81000 + AND $0x43210000, R4 // AND $1126236160, R4 // 1e42861484f81400 + AND $0x43210000, R5, R4 // AND $1126236160, R5, R4 // 1e428614a4f81400 + AND $0xffffffffc3210000, R4 // AND $-1021247488, R4 // 1e42861584f81400 + AND $0xffffffffc3210000, R5, R4 // AND $-1021247488, R5, R4 // 1e428615a4f81400 + + // AND C_ADDCON, [r1], r2 + AND $0xfffffffffffffc21, R4 // AND $-991, R4 // 1e84b00284f81400 + AND $0xfffffffffffffc21, R5, R4 // AND $-991, R5, R4 // 1e84b002a4f81400 diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc3.s b/src/cmd/asm/internal/asm/testdata/loong64enc3.s index 26008843..2d83bd71 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc3.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc3.s @@ -121,3 +121,68 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 XOR $74565, R4, R5 // 5e020014de178d0385f81500 XOR $4097, R4 // 3e000014de07800384f81500 XOR $4097, R4, R5 // 3e000014de07800385f81500 + + // MOVV C_DCON32_12S, r + MOVV $0x27312345fffff800, R4 // MOVV $2824077224892692480, R4 // 0400a002a468241684cc0903 + MOVV $0xf7312345fffff800, R4 // MOVV $-634687288927848448, R4 // 0400a002a468241684cc3d03 + + // MOVV C_DCON32_0, r + MOVV $0x2731234500000000, R4 // MOVV $2824077220597727232, R4 // 04008002a468241684cc0903 + MOVV $0xf731234500000000, R4 // MOVV $-634687293222813696, R4 // 04008002a468241684cc3d03 + + // MOVV C_DCON32_20, r + MOVV $0x2731234512345000, R4 // MOVV $2824077220903145472, R4 // a4682414a468241684cc0903 + MOVV $0xf731234512345000, R4 // MOVV $-634687292917395456, R4 // a4682414a468241684cc3d03 + + // MOVV C_DCON12_32S, r + MOVV $0x273fffff80000800, R4 // MOVV $2828260563841189888, R4 // 040000158400a00384cc0903 + MOVV $0xf73fffff80000800, R4 // MOVV $-630503949979351040, R4 // 040000158400a00384cc3d03 + + // MOVV C_DCON20S_32, r + MOVV $0xfff8000080000800, R4 // MOVV $-2251797666199552, R4 // 040000158400a00304000017 + + // MOVV C_DCON32_12U, r + MOVV $0x2731234500000800, R4 // MOVV $2824077220597729280, R4 // 0400a003a468241684cc0903 + MOVV $0xf731234500000800, R4 // MOVV $-634687293222811648, R4 // 0400a003a468241684cc3d03 + + // ADDV/AND C_DCON12_20S, [r1], r2 + ADDV $0x273fffff80000000, R4 // ADDV $2828260563841187840, R4 // 1e000015decf090384f81000 + ADDV $0x273fffff80000000, R4, R5 // ADDV $2828260563841187840, R4, R5 // 1e000015decf090385f81000 + AND $0x273fffff80000000, R4 // AND $2828260563841187840, R4 // 1e000015decf090384f81400 + AND $0x273fffff80000000, R4, R5 // AND $2828260563841187840, R4, R5 // 1e000015decf090385f81400 + + // ADDV/AND C_DCON20S_20, [r1], r2 + ADDV $0xfff800000f000000, R4 // ADDV $-2251799562027008, R4 // 1e001e141e00001784f81000 + ADDV $0xfff800000f000000, R4, R5 // ADDV $-2251799562027008, R4, R5 // 1e001e141e00001785f81000 + AND $0xfff800000f000000, R4 // AND $-2251799562027008, R4 // 1e001e141e00001784f81400 + AND $0xfff800000f000000, R4, R5 // AND $-2251799562027008, R4, R5 // 1e001e141e00001785f81400 + + // ADDV/AND C_DCON12_12S, [r1], r2 + ADDV $0x273ffffffffff800, R4 // ADDV $2828260565988669440, R4 // 1e00e002decf090384f81000 + ADDV $0x273ffffffffff800, R4, R5 // ADDV $2828260565988669440, R4, R5 // 1e00e002decf090385f81000 + AND $0x273ffffffffff800, R4 // AND $2828260565988669440, R4 // 1e00e002decf090384f81400 + AND $0x273ffffffffff800, R4, R5 // AND $2828260565988669440, R4, R5 // 1e00e002decf090385f81400 + + // ADDV/AND C_DCON20S_12S, [r1], r2 + ADDV $0xfff80000fffff800, R4 // ADDV $-2251795518720000, R4 // 1e00a0021e00001784f81000 + ADDV $0xfff80000fffff800, R4, R5 // ADDV $-2251795518720000, R4, R5 // 1e00a0021e00001785f81000 + AND $0xfff80000fffff800, R4 // AND $-2251795518720000, R4 // 1e00a0021e00001784f81400 + AND $0xfff80000fffff800, R4, R5 // AND $-2251795518720000, R4, R5 // 1e00a0021e00001785f81400 + + // ADDV/AND C_DCON20S_0, [r1], r2 + ADDV $0xfff8000000000000, R4 // ADDV $-2251799813685248, R4 // 1e0080021e00001784f81000 + ADDV $0xfff8000000000000, R4, R5 // ADDV $-2251799813685248, R4, R5 // 1e0080021e00001785f81000 + AND $0xfff8000000000000, R4 // AND $-2251799813685248, R4 // 1e0080021e00001784f81400 + AND $0xfff8000000000000, R4, R5 // AND $-2251799813685248, R4, R5 // 1e0080021e00001785f81400 + + // ADDV/AND C_DCON12_12U, [r1], r2 + ADDV $0x2730000000000800, R4 // ADDV $2823756966361303040, R4 // 1e00a003decf090384f81000 + ADDV $0x2730000000000800, R4, R5 // ADDV $2823756966361303040, R4, R5 // 1e00a003decf090385f81000 + AND $0x2730000000000800, R4 // AND $2823756966361303040, R4 // 1e00a003decf090384f81400 + AND $0x2730000000000800, R4, R5 // AND $2823756966361303040, R4, R5 // 1e00a003decf090385f81400 + + // ADDV/AND C_DCON20S_12U, [r1], r2 + ADDV $0xfff8000000000800, R4 // ADDV $-2251799813683200, R4 // 1e00a0031e00001784f81000 + ADDV $0xfff8000000000800, R4, R5 // ADDV $-2251799813683200, R4, R5 // 1e00a0031e00001785f81000 + AND $0xfff8000000000800, R4 // AND $-2251799813683200, R4 // 1e00a0031e00001784f81400 + AND $0xfff8000000000800, R4, R5 // AND $-2251799813683200, R4, R5 // 1e00a0031e00001785f81400 diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc4.s b/src/cmd/asm/internal/asm/testdata/loong64enc4.s new file mode 100644 index 00000000..16c06a35 --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/loong64enc4.s @@ -0,0 +1,42 @@ +// Copyright 2024 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. + +#include "../../../../../runtime/textflag.h" + +TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + // ADDV/AND C_DCON32_12S, [r1], r2 + ADDV $0x27312345fffff800, R4 // ADDV $2824077224892692480, R4 // 1e00a002be682416decf090384f81000 + ADDV $0x27312345fffff800, R4, R5 // ADDV $2824077224892692480, R4, R5 // 1e00a002be682416decf090385f81000 + AND $0x27312345fffff800, R4 // AND $2824077224892692480, R4 // 1e00a002be682416decf090384f81400 + AND $0x27312345fffff800, R4, R5 // AND $2824077224892692480, R4, R5 // 1e00a002be682416decf090385f81400 + + // ADDV/AND C_DCON32_0, [r1], r2 + ADDV $0x2731234500000000, R4 // ADDV $2824077220597727232, R4 // 1e008002be682416decf090384f81000 + ADDV $0x2731234500000000, R4, R5 // ADDV $2824077220597727232, R4, R5 // 1e008002be682416decf090385f81000 + AND $0x2731234500000000, R4 // AND $2824077220597727232, R4 // 1e008002be682416decf090384f81400 + AND $0x2731234500000000, R4, R5 // AND $2824077220597727232, R4, R5 // 1e008002be682416decf090385f81400 + + // ADDV/AND C_DCON32_20, [r1], r2 + ADDV $0x2731234512345000, R4 // ADDV $2824077220903145472, R4 // be682414be682416decf090384f81000 + ADDV $0x2731234512345000, R4, R5 // ADDV $2824077220903145472, R4, R5 // be682414be682416decf090385f81000 + AND $0x2731234512345000, R4 // AND $2824077220903145472, R4 // be682414be682416decf090384f81400 + AND $0x2731234512345000, R4, R5 // AND $2824077220903145472, R4, R5 // be682414be682416decf090385f81400 + + // ADDV/AND C_DCON12_32S, [r1], r2 + ADDV $0x273fffff80000800, R4 // ADDV $2828260563841189888, R4 // 1e000015de03a003decf090384f81000 + ADDV $0x273fffff80000800, R4, R5 // ADDV $2828260563841189888, R4, R5 // 1e000015de03a003decf090385f81000 + AND $0x273fffff80000800, R4 // AND $2828260563841189888, R4 // 1e000015de03a003decf090384f81400 + AND $0x273fffff80000800, R4, R5 // AND $2828260563841189888, R4, R5 // 1e000015de03a003decf090385f81400 + + // ADDV/AND C_DCON20S_32, [r1], r2 + ADDV $0xfff8000080000800, R4 // ADDV $-2251797666199552, R4 // 1e000015de03a0031e00001784f81000 + ADDV $0xfff8000080000800, R4, R5 // ADDV $-2251797666199552, R4, R5 // 1e000015de03a0031e00001785f81000 + AND $0xfff8000080000800, R4 // AND $-2251797666199552, R4 // 1e000015de03a0031e00001784f81400 + AND $0xfff8000080000800, R4, R5 // AND $-2251797666199552, R4, R5 // 1e000015de03a0031e00001785f81400 + + // ADDV/AND C_DCON32_12U, [r1], r2 + ADDV $0x2731234500000800, R4 // ADDV $2824077220597729280, R4 // 1e00a003be682416decf090384f81000 + ADDV $0x2731234500000800, R4, R5 // ADDV $2824077220597729280, R4, R5 // 1e00a003be682416decf090385f81000 + AND $0x2731234500000800, R4 // AND $2824077220597729280, R4 // 1e00a003be682416decf090384f81400 + AND $0x2731234500000800, R4, R5 // AND $2824077220597729280, R4, R5 // 1e00a003be682416decf090385f81400 diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc5.s b/src/cmd/asm/internal/asm/testdata/loong64enc5.s new file mode 100644 index 00000000..b7ecd6b6 --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/loong64enc5.s @@ -0,0 +1,22 @@ +// Copyright 2024 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. + +#include "../../../../../runtime/textflag.h" + +TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + // ADDV/AND C_DCON, [r1], r2 + ADDV $0xfedcba9876543210, R4 // ADDV $-81985529216486896, R4 // 7ea8ec14de4388031e539717deb73f0384f81000 + ADDV $0xfedcba9876543210, R5, R4 // ADDV $-81985529216486896, R5, R4 // 7ea8ec14de4388031e539717deb73f03a4f81000 + ADDV $0x4edcba9876543210, R4 // ADDV $5682621993817747984, R4 // 7ea8ec14de4388031e539717deb7130384f81000 + ADDV $0x4edcba9876543210, R5, R4 // ADDV $5682621993817747984, R5, R4 // 7ea8ec14de4388031e539717deb71303a4f81000 + AND $0x4edcba9876543210, R4 // AND $5682621993817747984, R4 // 7ea8ec14de4388031e539717deb7130384f81400 + AND $0x4edcba9876543210, R5, R4 // AND $5682621993817747984, R5, R4 // 7ea8ec14de4388031e539717deb71303a4f81400 + AND $0xfedcba9876543210, R4 // AND $-81985529216486896, R4 // 7ea8ec14de4388031e539717deb73f0384f81400 + AND $0xfedcba9876543210, R5, R4 // AND $-81985529216486896, R5, R4 // 7ea8ec14de4388031e539717deb73f03a4f81400 + + PRELDX 0(R7), $0x80001021, $0 // PRELDX (R7), $2147487777, $0 // 1e020014de0380031e000016de130003e0782c38 + PRELDX -1(R7), $0x1021, $2 // PRELDX -1(R7), $4129, $2 // fe030014deffbf031e000016de030003e2782c38 + PRELDX 8(R7), $0x80100800, $31 // PRELDX 8(R7), $2148534272, $31 // 1ee00714de238003fe1f0016de130003ff782c38 + PRELDX 16(R7), $0x202040, $1 // PRELDX 16(R7), $2105408, $1 // 1e200014de4380033e000216de030003e1782c38 + diff --git a/src/cmd/asm/internal/asm/testdata/loong64error.s b/src/cmd/asm/internal/asm/testdata/loong64error.s new file mode 100644 index 00000000..9272ce51 --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/loong64error.s @@ -0,0 +1,7 @@ +// Copyright 2025 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. + +TEXT errors(SB),$0 + VSHUF4IV $16, V1, V2 // ERROR "operand out of range 0 to 15" + XVSHUF4IV $16, X1, X2 // ERROR "operand out of range 0 to 15" diff --git a/src/cmd/asm/internal/asm/testdata/riscv64.s b/src/cmd/asm/internal/asm/testdata/riscv64.s index 37c0c1d8..75abcefa 100644 --- a/src/cmd/asm/internal/asm/testdata/riscv64.s +++ b/src/cmd/asm/internal/asm/testdata/riscv64.s @@ -363,6 +363,10 @@ start: SLLIUW $63, X17, X18 // 1b99f80b SLLIUW $1, X18, X19 // 9b191908 + // + // "B" Extension for Bit Manipulation, Version 1.0.0 + // + // 28.4.2: Basic Bit Manipulation (Zbb) ANDN X19, X20, X21 // b37a3a41 or 93caf9ffb37a5a01 ANDN X19, X20 // 337a3a41 or 93cff9ff337afa01 @@ -372,14 +376,14 @@ start: CPOPW X23, X24 // 1b9c2b60 CTZ X24, X25 // 931c1c60 CTZW X25, X26 // 1b9d1c60 - MAX X26, X28, X29 // b36eae0b - MAX X26, X28 // 336eae0b - MAXU X28, X29, X30 // 33ffce0b - MAXU X28, X29 // b3fece0b - MIN X29, X30, X5 // b342df0b - MIN X29, X30 // 334fdf0b - MINU X30, X5, X6 // 33d3e20b - MINU X30, X5 // b3d2e20b + MAX X26, X28, X29 // b36eae0b or b32fae01b30ff041b34eae01b3fedf01b34ede01 + MAX X26, X28 // 336eae0b or b32fcd01b30ff041334ecd0133fecf01334ecd01 + MAXU X28, X29, X30 // 33ffce0b or b3bfce01b30ff04133cfce0133ffef0133cfee01 + MAXU X28, X29 // b3fece0b or b33fde01b30ff041b34ede01b3fedf01b34ede01 + MIN X29, X30, X5 // b342df0b or b3afee01b30ff041b342df01b3f25f00b3425f00 + MIN X29, X30 // 334fdf0b or b32fdf01b30ff04133cfee0133ffef0133cfee01 + MINU X30, X5, X6 // 33d3e20b or b33f5f00b30ff04133c3e20133f36f0033c36200 + MINU X30, X5 // b3d2e20b or b3bfe201b30ff041b3425f00b3f25f00b3425f00 ORN X6, X7, X8 // 33e46340 or 1344f3ff33e48300 ORN X6, X7 // b3e36340 or 934ff3ffb3e3f301 SEXTB X16, X17 // 93184860 @@ -420,6 +424,866 @@ start: BSET $63, X9 // 9394f42b BSETI $1, X10, X11 // 93151528 + // + // "V" Standard Extension for Vector Operations, Version 1.0 + // + + // 31.6: Configuration Setting Instructions + VSETVLI X10, E8, M1, TU, MU, X12 // 57760500 + VSETVLI X10, E16, M1, TU, MU, X12 // 57768500 + VSETVLI X10, E32, M1, TU, MU, X12 // 57760501 + VSETVLI X10, E64, M1, TU, MU, X12 // 57768501 + VSETVLI X10, E32, M1, TU, MA, X12 // 57760509 + VSETVLI X10, E32, M1, TA, MA, X12 // 5776050d + VSETVLI X10, E32, M2, TA, MA, X12 // 5776150d + VSETVLI X10, E32, M4, TA, MA, X12 // 5776250d + VSETVLI X10, E32, M8, TA, MA, X12 // 5776350d + VSETVLI X10, E32, MF8, TA, MA, X12 // 5776550d + VSETVLI X10, E32, MF4, TA, MA, X12 // 5776650d + VSETVLI X10, E32, MF2, TA, MA, X12 // 5776750d + VSETVLI X10, E32, M1, TA, MA, X12 // 5776050d + VSETVLI $15, E32, M1, TA, MA, X12 // 57f607cd + VSETIVLI $0, E32, M1, TA, MA, X12 // 577600cd + VSETIVLI $15, E32, M1, TA, MA, X12 // 57f607cd + VSETIVLI $31, E32, M1, TA, MA, X12 // 57f60fcd + VSETVL X10, X11, X12 // 57f6a580 + + // 31.7.4: Vector Unit-Stride Instructions + VLE8V (X10), V3 // 87010502 + VLE8V (X10), V0, V3 // 87010500 + VLE16V (X10), V3 // 87510502 + VLE16V (X10), V0, V3 // 87510500 + VLE32V (X10), V3 // 87610502 + VLE32V (X10), V0, V3 // 87610500 + VLE64V (X10), V3 // 87710502 + VLE64V (X10), V0, V3 // 87710500 + VSE8V V3, (X10) // a7010502 + VSE8V V3, V0, (X10) // a7010500 + VSE16V V3, (X10) // a7510502 + VSE16V V3, V0, (X10) // a7510500 + VSE32V V3, (X10) // a7610502 + VSE32V V3, V0, (X10) // a7610500 + VSE64V V3, (X10) // a7710502 + VSE64V V3, V0, (X10) // a7710500 + VLMV (X10), V3 // 8701b502 + VSMV V3, (X10) // a701b502 + + // 31.7.5: Vector Strided Instructions + VLSE8V (X10), X11, V3 // 8701b50a + VLSE8V (X10), X11, V0, V3 // 8701b508 + VLSE16V (X10), X11, V3 // 8751b50a + VLSE16V (X10), X11, V0, V3 // 8751b508 + VLSE32V (X10), X11, V3 // 8761b50a + VLSE32V (X10), X11, V0, V3 // 8761b508 + VLSE64V (X10), X11, V3 // 8771b50a + VLSE64V (X10), X11, V0, V3 // 8771b508 + VSSE8V V3, X11, (X10) // a701b50a + VSSE8V V3, X11, V0, (X10) // a701b508 + VSSE16V V3, X11, (X10) // a751b50a + VSSE16V V3, X11, V0, (X10) // a751b508 + VSSE32V V3, X11, (X10) // a761b50a + VSSE32V V3, X11, V0, (X10) // a761b508 + VSSE64V V3, X11, (X10) // a771b50a + VSSE64V V3, X11, V0, (X10) // a771b508 + + // 31.7.6: Vector Indexed Instructions + VLUXEI8V (X10), V2, V3 // 87012506 + VLUXEI8V (X10), V2, V0, V3 // 87012504 + VLUXEI16V (X10), V2, V3 // 87512506 + VLUXEI16V (X10), V2, V0, V3 // 87512504 + VLUXEI32V (X10), V2, V3 // 87612506 + VLUXEI32V (X10), V2, V0, V3 // 87612504 + VLUXEI64V (X10), V2, V3 // 87712506 + VLUXEI64V (X10), V2, V0, V3 // 87712504 + VLOXEI8V (X10), V2, V3 // 8701250e + VLOXEI8V (X10), V2, V0, V3 // 8701250c + VLOXEI16V (X10), V2, V3 // 8751250e + VLOXEI16V (X10), V2, V0, V3 // 8751250c + VLOXEI32V (X10), V2, V3 // 8761250e + VLOXEI32V (X10), V2, V0, V3 // 8761250c + VLOXEI64V (X10), V2, V3 // 8771250e + VLOXEI64V (X10), V2, V0, V3 // 8771250c + VSUXEI8V V3, V2, (X10) // a7012506 + VSUXEI8V V3, V2, V0, (X10) // a7012504 + VSUXEI16V V3, V2, (X10) // a7512506 + VSUXEI16V V3, V2, V0, (X10) // a7512504 + VSUXEI32V V3, V2, (X10) // a7612506 + VSUXEI32V V3, V2, V0, (X10) // a7612504 + VSUXEI64V V3, V2, (X10) // a7712506 + VSUXEI64V V3, V2, V0, (X10) // a7712504 + VSOXEI8V V3, V2, (X10) // a701250e + VSOXEI8V V3, V2, V0, (X10) // a701250c + VSOXEI16V V3, V2, (X10) // a751250e + VSOXEI16V V3, V2, V0, (X10) // a751250c + VSOXEI32V V3, V2, (X10) // a761250e + VSOXEI32V V3, V2, V0, (X10) // a761250c + VSOXEI64V V3, V2, (X10) // a771250e + VSOXEI64V V3, V2, V0, (X10) // a771250c + + // 31.7.9: Vector Load/Store Whole Register Instructions + VL1RV (X10), V3 // 87018502 + VL1RE8V (X10), V3 // 87018502 + VL1RE16V (X10), V3 // 87518502 + VL1RE32V (X10), V3 // 87618502 + VL1RE64V (X10), V3 // 87718502 + VL2RV (X10), V2 // 07018522 + VL2RE8V (X10), V2 // 07018522 + VL2RE16V (X10), V2 // 07518522 + VL2RE32V (X10), V2 // 07618522 + VL2RE64V (X10), V2 // 07718522 + VL4RV (X10), V4 // 07028562 + VL4RE8V (X10), V4 // 07028562 + VL4RE16V (X10), V4 // 07528562 + VL4RE32V (X10), V4 // 07628562 + VL4RE64V (X10), V4 // 07728562 + VL8RV (X10), V8 // 070485e2 + VL8RE8V (X10), V8 // 070485e2 + VL8RE16V (X10), V8 // 075485e2 + VL8RE32V (X10), V8 // 076485e2 + VL8RE64V (X10), V8 // 077485e2 + VS1RV V3, (X11) // a7818502 + VS2RV V2, (X11) // 27818522 + VS4RV V4, (X11) // 27828562 + VS8RV V8, (X11) // 278485e2 + + // 31.11.1: Vector Single-Width Integer Add and Subtract + VADDVV V1, V2, V3 // d7812002 + VADDVV V1, V2, V0, V3 // d7812000 + VADDVX X10, V2, V3 // d7412502 + VADDVX X10, V2, V0, V3 // d7412500 + VADDVI $15, V2, V3 // d7b12702 + VADDVI $15, V2, V0, V3 // d7b12700 + VADDVI $-16, V2, V3 // d7312802 + VADDVI $-16, V2, V0, V3 // d7312800 + VSUBVV V1, V2, V3 // d781200a + VSUBVV V1, V2, V0, V3 // d7812008 + VSUBVX X10, V2, V3 // d741250a + VSUBVX X10, V2, V0, V3 // d7412508 + VRSUBVX X10, V2, V3 // d741250e + VRSUBVX X10, V2, V0, V3 // d741250c + VRSUBVI $15, V2, V0, V3 // d7b1270c + VRSUBVI $-16, V2, V0, V3 // d731280c + VNEGV V2, V3 // d741200e + VNEGV V2, V0, V3 // d741200c + + // 31.11.2: Vector Widening Integer Add/Subtract + VWADDUVV V1, V2, V3 // d7a120c2 + VWADDUVV V1, V2, V0, V3 // d7a120c0 + VWADDUVX X10, V2, V3 // d76125c2 + VWADDUVX X10, V2, V0, V3 // d76125c0 + VWSUBUVV V1, V2, V3 // d7a120ca + VWSUBUVV V1, V2, V0, V3 // d7a120c8 + VWSUBUVX X10, V2, V3 // d76125ca + VWSUBUVX X10, V2, V0, V3 // d76125c8 + VWADDVV V1, V2, V3 // d7a120c6 + VWADDVV V1, V2, V0, V3 // d7a120c4 + VWADDVX X10, V2, V3 // d76125c6 + VWADDVX X10, V2, V0, V3 // d76125c4 + VWSUBVV V1, V2, V3 // d7a120ce + VWSUBVV V1, V2, V0, V3 // d7a120cc + VWSUBVX X10, V2, V3 // d76125ce + VWSUBVX X10, V2, V0, V3 // d76125cc + VWADDUWV V1, V2, V3 // d7a120d2 + VWADDUWV V1, V2, V0, V3 // d7a120d0 + VWADDUWX X10, V2, V3 // d76125d2 + VWADDUWX X10, V2, V0, V3 // d76125d0 + VWSUBUWV V1, V2, V3 // d7a120da + VWSUBUWV V1, V2, V0, V3 // d7a120d8 + VWSUBUWX X10, V2, V3 // d76125da + VWSUBUWX X10, V2, V0, V3 // d76125d8 + VWADDWV V1, V2, V3 // d7a120d6 + VWADDWV V1, V2, V0, V3 // d7a120d4 + VWADDWX X10, V2, V3 // d76125d6 + VWADDWX X10, V2, V0, V3 // d76125d4 + VWSUBWV V1, V2, V3 // d7a120de + VWSUBWV V1, V2, V0, V3 // d7a120dc + VWSUBWX X10, V2, V3 // d76125de + VWSUBWX X10, V2, V0, V3 // d76125dc + VWCVTXXV V2, V3 // d76120c6 + VWCVTXXV V2, V0, V3 // d76120c4 + VWCVTUXXV V2, V3 // d76120c2 + VWCVTUXXV V2, V0, V3 // d76120c0 + + // 31.11.3: Vector Integer Extension + VZEXTVF2 V2, V3 // d721234a + VZEXTVF2 V2, V0, V3 // d7212348 + VSEXTVF2 V2, V3 // d7a1234a + VSEXTVF2 V2, V0, V3 // d7a12348 + VZEXTVF4 V2, V3 // d721224a + VZEXTVF4 V2, V0, V3 // d7212248 + VSEXTVF4 V2, V3 // d7a1224a + VSEXTVF4 V2, V0, V3 // d7a12248 + VZEXTVF8 V2, V3 // d721214a + VZEXTVF8 V2, V0, V3 // d7212148 + VSEXTVF8 V2, V3 // d7a1214a + VSEXTVF8 V2, V0, V3 // d7a12148 + + // 31.11.4: Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions + VADCVVM V1, V2, V0, V3 // d7812040 + VADCVXM X11, V2, V0, V3 // d7c12540 + VADCVIM $15, V2, V0, V3 // d7b12740 + VMADCVVM V1, V2, V0, V3 // d7812044 + VMADCVVM V1, V2, V0, V0 // 57802044 + VMADCVXM X11, V2, V0, V3 // d7c12544 + VMADCVXM X11, V2, V0, V0 // 57c02544 + VMADCVIM $15, V2, V0, V3 // d7b12744 + VMADCVIM $15, V2, V0, V0 // 57b02744 + VMADCVV V1, V2, V3 // d7812046 + VMADCVV V1, V2, V0 // 57802046 + VMADCVX X11, V2, V3 // d7c12546 + VMADCVX X11, V2, V0 // 57c02546 + VMADCVI $15, V2, V3 // d7b12746 + VMADCVI $15, V2, V0 // 57b02746 + VSBCVVM V1, V2, V0, V3 // d7812048 + VSBCVXM X11, V2, V0, V3 // d7c12548 + VMSBCVVM V1, V2, V0, V3 // d781204c + VMSBCVVM V1, V2, V0, V0 // 5780204c + VMSBCVXM X11, V2, V0, V3 // d7c1254c + VMSBCVXM X11, V2, V0, V0 // 57c0254c + VMSBCVV V1, V2, V3 // d781204e + VMSBCVV V1, V2, V0 // 5780204e + VMSBCVX X11, V2, V3 // d7c1254e + VMSBCVX X11, V2, V0 // 57c0254e + + // 31.11.5: Vector Bitwise Logical Instructions + VANDVV V1, V2, V3 // d7812026 + VANDVV V1, V2, V0, V3 // d7812024 + VANDVX X11, V2, V3 // d7c12526 + VANDVX X11, V2, V0, V3 // d7c12524 + VANDVI $15, V2, V3 // d7b12726 + VANDVI $15, V2, V0, V3 // d7b12724 + VORVV V1, V2, V3 // d781202a + VORVV V1, V2, V0, V3 // d7812028 + VORVX X11, V2, V3 // d7c1252a + VORVX X11, V2, V0, V3 // d7c12528 + VORVI $15, V2, V3 // d7b1272a + VORVI $15, V2, V0, V3 // d7b12728 + VXORVV V1, V2, V3 // d781202e + VXORVV V1, V2, V0, V3 // d781202c + VXORVX X11, V2, V3 // d7c1252e + VXORVX X11, V2, V0, V3 // d7c1252c + VXORVI $15, V2, V3 // d7b1272e + VXORVI $15, V2, V0, V3 // d7b1272c + VNOTV V2, V3 // d7b12f2e + VNOTV V2, V0, V3 // d7b12f2c + + // 31.11.6: Vector Single-Width Shift Instructions + VSLLVV V1, V2, V3 // d7812096 + VSLLVV V1, V2, V0, V3 // d7812094 + VSLLVX X11, V2, V3 // d7c12596 + VSLLVX X11, V2, V0, V3 // d7c12594 + VSLLVI $15, V2, V3 // d7b12796 + VSLLVI $15, V2, V0, V3 // d7b12794 + VSRLVV V1, V2, V3 // d78120a2 + VSRLVV V1, V2, V0, V3 // d78120a0 + VSRLVX X11, V2, V3 // d7c125a2 + VSRLVX X11, V2, V0, V3 // d7c125a0 + VSRLVI $15, V2, V3 // d7b127a2 + VSRLVI $15, V2, V0, V3 // d7b127a0 + VSRAVV V1, V2, V3 // d78120a6 + VSRAVV V1, V2, V0, V3 // d78120a4 + VSRAVX X11, V2, V3 // d7c125a6 + VSRAVX X11, V2, V0, V3 // d7c125a4 + VSRAVI $15, V2, V3 // d7b127a6 + VSRAVI $15, V2, V0, V3 // d7b127a4 + + // 31.11.7: Vector Narrowing Integer Right Shift Instructions + VNSRLWV V1, V2, V3 // d78120b2 + VNSRLWV V1, V2, V0, V3 // d78120b0 + VNSRLWX X10, V2, V3 // d74125b2 + VNSRLWX X10, V2, V0, V3 // d74125b0 + VNSRLWI $31, V2, V3 // d7b12fb2 + VNSRLWI $31, V2, V0, V3 // d7b12fb0 + VNSRAWV V1, V2, V3 // d78120b6 + VNSRAWV V1, V2, V0, V3 // d78120b4 + VNSRAWX X10, V2, V3 // d74125b6 + VNSRAWX X10, V2, V0, V3 // d74125b4 + VNSRAWI $31, V2, V3 // d7b12fb6 + VNSRAWI $31, V2, V0, V3 // d7b12fb4 + VNCVTXXW V2, V3 // d74120b2 + VNCVTXXW V2, V0, V3 // d74120b0 + + // 31.11.8: Vector Integer Compare Instructions + VMSEQVV V1, V2, V3 // d7812062 + VMSEQVV V1, V2, V0, V3 // d7812060 + VMSEQVX X10, V2, V3 // d7412562 + VMSEQVX X10, V2, V0, V3 // d7412560 + VMSEQVI $15, V2, V3 // d7b12762 + VMSEQVI $15, V2, V0, V3 // d7b12760 + VMSNEVV V1, V2, V3 // d7812066 + VMSNEVV V1, V2, V0, V3 // d7812064 + VMSNEVX X10, V2, V3 // d7412566 + VMSNEVX X10, V2, V0, V3 // d7412564 + VMSNEVI $15, V2, V3 // d7b12766 + VMSNEVI $15, V2, V0, V3 // d7b12764 + VMSLTUVV V1, V2, V3 // d781206a + VMSLTUVV V1, V2, V0, V3 // d7812068 + VMSLTUVX X10, V2, V3 // d741256a + VMSLTUVX X10, V2, V0, V3 // d7412568 + VMSLTVV V1, V2, V3 // d781206e + VMSLTVV V1, V2, V0, V3 // d781206c + VMSLTVX X10, V2, V3 // d741256e + VMSLTVX X10, V2, V0, V3 // d741256c + VMSLEUVV V1, V2, V3 // d7812072 + VMSLEUVV V1, V2, V0, V3 // d7812070 + VMSLEUVX X10, V2, V3 // d7412572 + VMSLEUVX X10, V2, V0, V3 // d7412570 + VMSLEUVI $15, V2, V3 // d7b12772 + VMSLEUVI $15, V2, V0, V3 // d7b12770 + VMSLEVV V1, V2, V3 // d7812076 + VMSLEVV V1, V2, V0, V3 // d7812074 + VMSLEVX X10, V2, V3 // d7412576 + VMSLEVX X10, V2, V0, V3 // d7412574 + VMSLEVI $15, V2, V3 // d7b12776 + VMSLEVI $15, V2, V0, V3 // d7b12774 + VMSGTUVX X10, V2, V3 // d741257a + VMSGTUVX X10, V2, V0, V3 // d7412578 + VMSGTUVI $15, V2, V3 // d7b1277a + VMSGTUVI $15, V2, V0, V3 // d7b12778 + VMSGTVX X10, V2, V3 // d741257e + VMSGTVX X10, V2, V0, V3 // d741257c + VMSGTVI $15, V2, V3 // d7b1277e + VMSGTVI $15, V2, V0, V3 // d7b1277c + VMSGTVV V1, V2, V3 // d701116e + VMSGTVV V1, V2, V0, V3 // d701116c + VMSGTUVV V1, V2, V3 // d701116a + VMSGTUVV V1, V2, V0, V3 // d7011168 + VMSGEVV V1, V2, V3 // d7011176 + VMSGEVV V1, V2, V0, V3 // d7011174 + VMSGEUVV V1, V2, V3 // d7011172 + VMSGEUVV V1, V2, V0, V3 // d7011170 + VMSLTVI $15, V2, V3 // d7312776 + VMSLTVI $15, V2, V0, V3 // d7312774 + VMSLTUVI $15, V2, V3 // d7312772 + VMSLTUVI $15, V2, V0, V3 // d7312770 + VMSGEVI $15, V2, V3 // d731277e + VMSGEVI $15, V2, V0, V3 // d731277c + VMSGEUVI $15, V2, V3 // d731277a + VMSGEUVI $15, V2, V0, V3 // d7312778 + + // 31.11.9: Vector Integer Min/Max Instructions + VMINUVV V1, V2, V3 // d7812012 + VMINUVV V1, V2, V0, V3 // d7812010 + VMINUVX X10, V2, V3 // d7412512 + VMINUVX X10, V2, V0, V3 // d7412510 + VMINVV V1, V2, V3 // d7812016 + VMINVV V1, V2, V0, V3 // d7812014 + VMINVX X10, V2, V3 // d7412516 + VMINVX X10, V2, V0, V3 // d7412514 + VMAXUVV V1, V2, V3 // d781201a + VMAXUVV V1, V2, V0, V3 // d7812018 + VMAXUVX X10, V2, V3 // d741251a + VMAXUVX X10, V2, V0, V3 // d7412518 + VMAXVV V1, V2, V3 // d781201e + VMAXVV V1, V2, V0, V3 // d781201c + VMAXVX X10, V2, V3 // d741251e + VMAXVX X10, V2, V0, V3 // d741251c + + // 31.11.10: Vector Single-Width Integer Multiply Instructions + VMULVV V1, V2, V3 // d7a12096 + VMULVV V1, V2, V0, V3 // d7a12094 + VMULVX X10, V2, V3 // d7612596 + VMULVX X10, V2, V0, V3 // d7612594 + VMULHVV V1, V2, V3 // d7a1209e + VMULHVV V1, V2, V0, V3 // d7a1209c + VMULHVX X10, V2, V3 // d761259e + VMULHVX X10, V2, V0, V3 // d761259c + VMULHUVV V1, V2, V3 // d7a12092 + VMULHUVV V1, V2, V0, V3 // d7a12090 + VMULHUVX X10, V2, V3 // d7612592 + VMULHUVX X10, V2, V0, V3 // d7612590 + VMULHSUVV V1, V2, V3 // d7a1209a + VMULHSUVV V1, V2, V0, V3 // d7a12098 + VMULHSUVX X10, V2, V3 // d761259a + VMULHSUVX X10, V2, V0, V3 // d7612598 + + // 31.11.11: Vector Integer Divide Instructions + VDIVUVV V1, V2, V3 // d7a12082 + VDIVUVV V1, V2, V0, V3 // d7a12080 + VDIVUVX X10, V2, V3 // d7612582 + VDIVUVX X10, V2, V0, V3 // d7612580 + VDIVVV V1, V2, V3 // d7a12086 + VDIVVV V1, V2, V0, V3 // d7a12084 + VDIVVX X10, V2, V3 // d7612586 + VDIVVX X10, V2, V0, V3 // d7612584 + VREMUVV V1, V2, V3 // d7a1208a + VREMUVV V1, V2, V0, V3 // d7a12088 + VREMUVX X10, V2, V3 // d761258a + VREMUVX X10, V2, V0, V3 // d7612588 + VREMVV V1, V2, V3 // d7a1208e + VREMVV V1, V2, V0, V3 // d7a1208c + VREMVX X10, V2, V3 // d761258e + VREMVX X10, V2, V0, V3 // d761258c + + // 31.11.12: Vector Widening Integer Multiply Instructions + VWMULVV V1, V2, V3 // d7a120ee + VWMULVV V1, V2, V0, V3 // d7a120ec + VWMULVX X10, V2, V3 // d76125ee + VWMULVX X10, V2, V0, V3 // d76125ec + VWMULUVV V1, V2, V3 // d7a120e2 + VWMULUVV V1, V2, V0, V3 // d7a120e0 + VWMULUVX X10, V2, V3 // d76125e2 + VWMULUVX X10, V2, V0, V3 // d76125e0 + VWMULSUVV V1, V2, V3 // d7a120ea + VWMULSUVV V1, V2, V0, V3 // d7a120e8 + VWMULSUVX X10, V2, V3 // d76125ea + VWMULSUVX X10, V2, V0, V3 // d76125e8 + + // 31.11.13: Vector Single-Width Integer Multiply-Add Instructions + VMACCVV V2, V1, V3 // d7a120b6 + VMACCVV V2, V1, V0, V3 // d7a120b4 + VMACCVX V2, X10, V3 // d76125b6 + VMACCVX V2, X10, V0, V3 // d76125b4 + VNMSACVV V2, V1, V3 // d7a120be + VNMSACVV V2, V1, V0, V3 // d7a120bc + VNMSACVX V2, X10, V3 // d76125be + VNMSACVX V2, X10, V0, V3 // d76125bc + VMADDVV V2, V1, V3 // d7a120a6 + VMADDVV V2, V1, V0, V3 // d7a120a4 + VMADDVX V2, X10, V3 // d76125a6 + VMADDVX V2, X10, V0, V3 // d76125a4 + VNMSUBVV V2, V1, V3 // d7a120ae + VNMSUBVV V2, V1, V0, V3 // d7a120ac + VNMSUBVX V2, X10, V3 // d76125ae + VNMSUBVX V2, X10, V0, V3 // d76125ac + + // 31.11.14: Vector Widening Integer Multiply-Add Instructions + VWMACCUVV V2, V1, V3 // d7a120f2 + VWMACCUVV V2, V1, V0, V3 // d7a120f0 + VWMACCUVX V2, X10, V3 // d76125f2 + VWMACCUVX V2, X10, V0, V3 // d76125f0 + VWMACCVV V2, V1, V3 // d7a120f6 + VWMACCVV V2, V1, V0, V3 // d7a120f4 + VWMACCVX V2, X10, V3 // d76125f6 + VWMACCVX V2, X10, V0, V3 // d76125f4 + VWMACCSUVV V2, V1, V3 // d7a120fe + VWMACCSUVV V2, V1, V0, V3 // d7a120fc + VWMACCSUVX V2, X10, V3 // d76125fe + VWMACCSUVX V2, X10, V0, V3 // d76125fc + VWMACCUSVX V2, X10, V3 // d76125fa + VWMACCUSVX V2, X10, V0, V3 // d76125f8 + + // 31.11.15: Vector Integer Merge Instructions + VMERGEVVM V1, V2, V0, V3 // d781205c + VMERGEVXM X10, V2, V0, V3 // d741255c + VMERGEVIM $15, V2, V0, V3 // d7b1275c + + // 31.11.16: Vector Integer Move Instructions + VMVVV V2, V3 // d701015e + VMVVX X10, V3 // d741055e + VMVVI $15, V3 // d7b1075e + + // 31.12.1: Vector Single-Width Saturating Add and Subtract + VSADDUVV V1, V2, V3 // d7812082 + VSADDUVV V1, V2, V0, V3 // d7812080 + VSADDUVX X10, V2, V3 // d7412582 + VSADDUVX X10, V2, V0, V3 // d7412580 + VSADDUVI $15, V2, V3 // d7b12782 + VSADDUVI $15, V2, V0, V3 // d7b12780 + VSADDVV V1, V2, V3 // d7812086 + VSADDVV V1, V2, V0, V3 // d7812084 + VSADDVX X10, V2, V3 // d7412586 + VSADDVX X10, V2, V0, V3 // d7412584 + VSADDVI $15, V2, V3 // d7b12786 + VSADDVI $15, V2, V0, V3 // d7b12784 + VSSUBUVV V1, V2, V3 // d781208a + VSSUBUVV V1, V2, V0, V3 // d7812088 + VSSUBUVX X10, V2, V3 // d741258a + VSSUBUVX X10, V2, V0, V3 // d7412588 + VSSUBVV V1, V2, V3 // d781208e + VSSUBVV V1, V2, V0, V3 // d781208c + VSSUBVX X10, V2, V3 // d741258e + VSSUBVX X10, V2, V0, V3 // d741258c + + // 31.12.2: Vector Single-Width Averaging Add and Subtract + VAADDUVV V1, V2, V3 // d7a12022 + VAADDUVV V1, V2, V0, V3 // d7a12020 + VAADDUVX X10, V2, V3 // d7612522 + VAADDUVX X10, V2, V0, V3 // d7612520 + VAADDVV V1, V2, V3 // d7a12026 + VAADDVV V1, V2, V0, V3 // d7a12024 + VAADDVX X10, V2, V3 // d7612526 + VAADDVX X10, V2, V0, V3 // d7612524 + VASUBUVV V1, V2, V3 // d7a1202a + VASUBUVV V1, V2, V0, V3 // d7a12028 + VASUBUVX X10, V2, V3 // d761252a + VASUBUVX X10, V2, V0, V3 // d7612528 + VASUBVV V1, V2, V3 // d7a1202e + VASUBVV V1, V2, V0, V3 // d7a1202c + VASUBVX X10, V2, V3 // d761252e + VASUBVX X10, V2, V0, V3 // d761252c + + // 31.12.3: Vector Single-Width Fractional Multiply with Rounding and Saturation + VSMULVV V1, V2, V3 // d781209e + VSMULVV V1, V2, V0, V3 // d781209c + VSMULVX X10, V2, V3 // d741259e + VSMULVX X10, V2, V0, V3 // d741259c + + // 31.12.4: Vector Single-Width Scaling Shift Instructions + VSSRLVV V1, V2, V3 // d78120aa + VSSRLVV V1, V2, V0, V3 // d78120a8 + VSSRLVX X10, V2, V3 // d74125aa + VSSRLVX X10, V2, V0, V3 // d74125a8 + VSSRLVI $15, V2, V3 // d7b127aa + VSSRLVI $15, V2, V0, V3 // d7b127a8 + VSSRAVV V1, V2, V3 // d78120ae + VSSRAVV V1, V2, V0, V3 // d78120ac + VSSRAVX X10, V2, V3 // d74125ae + VSSRAVX X10, V2, V0, V3 // d74125ac + VSSRAVI $16, V2, V3 // d73128ae + VSSRAVI $16, V2, V0, V3 // d73128ac + + // 31.12.5: Vector Narrowing Fixed-Point Clip Instructions + VNCLIPUWV V1, V2, V3 // d78120ba + VNCLIPUWV V1, V2, V0, V3 // d78120b8 + VNCLIPUWX X10, V2, V3 // d74125ba + VNCLIPUWX X10, V2, V0, V3 // d74125b8 + VNCLIPUWI $16, V2, V3 // d73128ba + VNCLIPUWI $16, V2, V0, V3 // d73128b8 + VNCLIPWV V1, V2, V3 // d78120be + VNCLIPWV V1, V2, V0, V3 // d78120bc + VNCLIPWX X10, V2, V3 // d74125be + VNCLIPWX X10, V2, V0, V3 // d74125bc + VNCLIPWI $16, V2, V3 // d73128be + VNCLIPWI $16, V2, V0, V3 // d73128bc + + // 31.13.2: Vector Single-Width Floating-Point Add/Subtract Instructions + VFADDVV V1, V2, V3 // d7912002 + VFADDVV V1, V2, V0, V3 // d7912000 + VFADDVF F10, V2, V3 // d7512502 + VFADDVF F10, V2, V0, V3 // d7512500 + VFSUBVV V1, V2, V3 // d791200a + VFSUBVV V1, V2, V0, V3 // d7912008 + VFSUBVF F10, V2, V3 // d751250a + VFSUBVF F10, V2, V0, V3 // d7512508 + VFRSUBVF F10, V2, V3 // d751259e + VFRSUBVF F10, V2, V0, V3 // d751259c + + // 31.13.3: Vector Widening Floating-Point Add/Subtract Instructions + VFWADDVV V1, V2, V3 // d79120c2 + VFWADDVV V1, V2, V0, V3 // d79120c0 + VFWADDVF F10, V2, V3 // d75125c2 + VFWADDVF F10, V2, V0, V3 // d75125c0 + VFWSUBVV V1, V2, V3 // d79120ca + VFWSUBVV V1, V2, V0, V3 // d79120c8 + VFWSUBVF F10, V2, V3 // d75125ca + VFWSUBVF F10, V2, V0, V3 // d75125c8 + VFWADDWV V1, V2, V3 // d79120d2 + VFWADDWV V1, V2, V0, V3 // d79120d0 + VFWADDWF F10, V2, V3 // d75125d2 + VFWADDWF F10, V2, V0, V3 // d75125d0 + VFWSUBWV V1, V2, V3 // d79120da + VFWSUBWV V1, V2, V0, V3 // d79120d8 + VFWSUBWF F10, V2, V3 // d75125da + VFWSUBWF F10, V2, V0, V3 // d75125d8 + + // 31.13.4: Vector Single-Width Floating-Point Multiply/Divide Instructions + VFMULVV V1, V2, V3 // d7912092 + VFMULVV V1, V2, V0, V3 // d7912090 + VFMULVF F10, V2, V3 // d7512592 + VFMULVF F10, V2, V0, V3 // d7512590 + VFDIVVV V1, V2, V3 // d7912082 + VFDIVVV V1, V2, V0, V3 // d7912080 + VFDIVVF F10, V2, V3 // d7512582 + VFDIVVF F10, V2, V0, V3 // d7512580 + VFRDIVVF F10, V2, V3 // d7512586 + VFRDIVVF F10, V2, V0, V3 // d7512584 + + // 31.13.5: Vector Widening Floating-Point Multiply + VFWMULVV V1, V2, V3 // d79120e2 + VFWMULVV V1, V2, V0, V3 // d79120e0 + VFWMULVF F10, V2, V3 // d75125e2 + VFWMULVF F10, V2, V0, V3 // d75125e0 + + // 31.13.6: Vector Single-Width Floating-Point Fused Multiply-Add Instructions + VFMACCVV V2, V1, V3 // d79120b2 + VFMACCVV V2, V1, V0, V3 // d79120b0 + VFMACCVF V2, F10, V3 // d75125b2 + VFMACCVF V2, F10, V0, V3 // d75125b0 + VFNMACCVV V2, V1, V3 // d79120b6 + VFNMACCVV V2, V1, V0, V3 // d79120b4 + VFNMACCVF V2, F10, V3 // d75125b6 + VFNMACCVF V2, F10, V0, V3 // d75125b4 + VFMSACVV V2, V1, V3 // d79120ba + VFMSACVV V2, V1, V0, V3 // d79120b8 + VFMSACVF V2, F10, V3 // d75125ba + VFMSACVF V2, F10, V0, V3 // d75125b8 + VFNMSACVV V2, V1, V3 // d79120be + VFNMSACVV V2, V1, V0, V3 // d79120bc + VFNMSACVF V2, F10, V3 // d75125be + VFNMSACVF V2, F10, V0, V3 // d75125bc + VFMADDVV V2, V1, V3 // d79120a2 + VFMADDVV V2, V1, V0, V3 // d79120a0 + VFMADDVF V2, F10, V3 // d75125a2 + VFMADDVF V2, F10, V0, V3 // d75125a0 + VFNMADDVV V2, V1, V3 // d79120a6 + VFNMADDVV V2, V1, V0, V3 // d79120a4 + VFNMADDVF V2, F10, V3 // d75125a6 + VFNMADDVF V2, F10, V0, V3 // d75125a4 + VFMSUBVV V2, V1, V3 // d79120aa + VFMSUBVV V2, V1, V0, V3 // d79120a8 + VFMSUBVF V2, F10, V3 // d75125aa + VFMSUBVF V2, F10, V0, V3 // d75125a8 + VFNMSUBVV V2, V1, V3 // d79120ae + VFNMSUBVV V2, V1, V0, V3 // d79120ac + VFNMSUBVF V2, F10, V3 // d75125ae + VFNMSUBVF V2, F10, V0, V3 // d75125ac + + // 31.13.7: Vector Widening Floating-Point Fused Multiply-Add Instructions + VFWMACCVV V2, V1, V3 // d79120f2 + VFWMACCVV V2, V1, V0, V3 // d79120f0 + VFWMACCVF V2, F10, V3 // d75125f2 + VFWMACCVF V2, F10, V0, V3 // d75125f0 + VFWNMACCVV V2, V1, V3 // d79120f6 + VFWNMACCVV V2, V1, V0, V3 // d79120f4 + VFWNMACCVF V2, F10, V3 // d75125f6 + VFWNMACCVF V2, F10, V0, V3 // d75125f4 + VFWMSACVV V2, V1, V3 // d79120fa + VFWMSACVV V2, V1, V0, V3 // d79120f8 + VFWMSACVF V2, F10, V3 // d75125fa + VFWMSACVF V2, F10, V0, V3 // d75125f8 + VFWNMSACVV V2, V1, V3 // d79120fe + VFWNMSACVV V2, V1, V0, V3 // d79120fc + VFWNMSACVF V2, F10, V3 // d75125fe + VFWNMSACVF V2, F10, V0, V3 // d75125fc + + // 31.13.8: Vector Floating-Point Square-Root Instruction + VFSQRTV V2, V3 // d711204e + VFSQRTV V2, V0, V3 // d711204c + + // 31.13.9: Vector Floating-Point Reciprocal Square-Root Estimate Instruction + VFRSQRT7V V2, V3 // d711224e + VFRSQRT7V V2, V0, V3 // d711224c + + // 31.13.10: Vector Floating-Point Reciprocal Estimate Instruction + VFREC7V V2, V3 // d791224e + VFREC7V V2, V0, V3 // d791224c + + // 31.13.11: Vector Floating-Point MIN/MAX Instructions + VFMINVV V1, V2, V3 // d7912012 + VFMINVV V1, V2, V0, V3 // d7912010 + VFMINVF F10, V2, V3 // d7512512 + VFMINVF F10, V2, V0, V3 // d7512510 + VFMAXVV V1, V2, V3 // d791201a + VFMAXVV V1, V2, V0, V3 // d7912018 + VFMAXVF F10, V2, V3 // d751251a + VFMAXVF F10, V2, V0, V3 // d7512518 + + // 31.13.12: Vector Floating-Point Sign-Injection Instructions + VFSGNJVV V1, V2, V3 // d7912022 + VFSGNJVV V1, V2, V0, V3 // d7912020 + VFSGNJVF F10, V2, V3 // d7512522 + VFSGNJVF F10, V2, V0, V3 // d7512520 + VFSGNJNVV V1, V2, V3 // d7912026 + VFSGNJNVV V1, V2, V0, V3 // d7912024 + VFSGNJNVF F10, V2, V3 // d7512526 + VFSGNJNVF F10, V2, V0, V3 // d7512524 + VFSGNJXVV V1, V2, V3 // d791202a + VFSGNJXVV V1, V2, V0, V3 // d7912028 + VFSGNJXVF F10, V2, V3 // d751252a + VFSGNJXVF F10, V2, V0, V3 // d7512528 + VFNEGV V2, V3 // d7112126 + VFNEGV V2, V0, V3 // d7112124 + VFABSV V2, V3 // d711212a + VFABSV V2, V0, V3 // d7112128 + + // 31.13.13: Vector Floating-Point Compare Instructions + VMFEQVV V1, V2, V3 // d7912062 + VMFEQVV V1, V2, V0, V3 // d7912060 + VMFEQVF F10, V2, V3 // d7512562 + VMFEQVF F10, V2, V0, V3 // d7512560 + VMFNEVV V1, V2, V3 // d7912072 + VMFNEVV V1, V2, V0, V3 // d7912070 + VMFNEVF F10, V2, V3 // d7512572 + VMFNEVF F10, V2, V0, V3 // d7512570 + VMFLTVV V1, V2, V3 // d791206e + VMFLTVV V1, V2, V0, V3 // d791206c + VMFLTVF F10, V2, V3 // d751256e + VMFLTVF F10, V2, V0, V3 // d751256c + VMFLEVV V1, V2, V3 // d7912066 + VMFLEVV V1, V2, V0, V3 // d7912064 + VMFLEVF F10, V2, V3 // d7512566 + VMFLEVF F10, V2, V0, V3 // d7512564 + VMFGTVF F10, V2, V3 // d7512576 + VMFGTVF F10, V2, V0, V3 // d7512574 + VMFGEVF F10, V2, V3 // d751257e + VMFGEVF F10, V2, V0, V3 // d751257c + VMFGTVV V1, V2, V3 // d711116e + VMFGTVV V1, V2, V0, V3 // d711116c + VMFGEVV V1, V2, V3 // d7111166 + VMFGEVV V1, V2, V0, V3 // d7111164 + + // 31.13.14: Vector Floating-Point Classify Instruction + VFCLASSV V2, V3 // d711284e + VFCLASSV V2, V0, V3 // d711284c + + // 31.13.15: Vector Floating-Point Merge Instruction + VFMERGEVFM F10, V2, V0, V3 // d751255c + + // 31.13.16: Vector Floating-Point Move Instruction + VFMVVF F10, V3 // d751055e + + // 31.13.17: Single-Width Floating-Point/Integer Type-Convert Instructions + VFCVTXUFV V2, V3 // d711204a + VFCVTXUFV V2, V0, V3 // d7112048 + VFCVTXFV V2, V3 // d791204a + VFCVTXFV V2, V0, V3 // d7912048 + VFCVTRTZXUFV V2, V3 // d711234a + VFCVTRTZXUFV V2, V0, V3 // d7112348 + VFCVTRTZXFV V2, V3 // d791234a + VFCVTRTZXFV V2, V0, V3 // d7912348 + VFCVTFXUV V2, V3 // d711214a + VFCVTFXUV V2, V0, V3 // d7112148 + VFCVTFXV V2, V3 // d791214a + VFCVTFXV V2, V0, V3 // d7912148 + + // 31.13.18: Widening Floating-Point/Integer Type-Convert Instructions + VFWCVTXUFV V2, V3 // d711244a + VFWCVTXUFV V2, V0, V3 // d7112448 + VFWCVTXFV V2, V3 // d791244a + VFWCVTXFV V2, V0, V3 // d7912448 + VFWCVTRTZXUFV V2, V3 // d711274a + VFWCVTRTZXUFV V2, V0, V3 // d7112748 + VFWCVTRTZXFV V2, V3 // d791274a + VFWCVTRTZXFV V2, V0, V3 // d7912748 + VFWCVTFXUV V2, V3 // d711254a + VFWCVTFXUV V2, V0, V3 // d7112548 + VFWCVTFXV V2, V3 // d791254a + VFWCVTFXV V2, V0, V3 // d7912548 + VFWCVTFFV V2, V3 // d711264a + VFWCVTFFV V2, V0, V3 // d7112648 + + // 31.13.19: Narrowing Floating-Point/Integer Type-Convert Instructions + VFNCVTXUFW V2, V3 // d711284a + VFNCVTXUFW V2, V0, V3 // d7112848 + VFNCVTXFW V2, V3 // d791284a + VFNCVTXFW V2, V0, V3 // d7912848 + VFNCVTRTZXUFW V2, V3 // d7112b4a + VFNCVTRTZXUFW V2, V0, V3 // d7112b48 + VFNCVTRTZXFW V2, V3 // d7912b4a + VFNCVTRTZXFW V2, V0, V3 // d7912b48 + VFNCVTFXUW V2, V3 // d711294a + VFNCVTFXUW V2, V0, V3 // d7112948 + VFNCVTFXW V2, V3 // d791294a + VFNCVTFXW V2, V0, V3 // d7912948 + VFNCVTFFW V2, V3 // d7112a4a + VFNCVTFFW V2, V0, V3 // d7112a48 + VFNCVTRODFFW V2, V3 // d7912a4a + VFNCVTRODFFW V2, V0, V3 // d7912a48 + + // 31.14.1: Vector Single-Width Integer Reduction Instructions + VREDSUMVS V1, V2, V3 // d7a12002 + VREDSUMVS V1, V2, V0, V3 // d7a12000 + VREDMAXUVS V1, V2, V3 // d7a1201a + VREDMAXUVS V1, V2, V0, V3 // d7a12018 + VREDMAXVS V1, V2, V3 // d7a1201e + VREDMAXVS V1, V2, V0, V3 // d7a1201c + VREDMINUVS V1, V2, V3 // d7a12012 + VREDMINUVS V1, V2, V0, V3 // d7a12010 + VREDMINVS V1, V2, V3 // d7a12016 + VREDMINVS V1, V2, V0, V3 // d7a12014 + VREDANDVS V1, V2, V3 // d7a12006 + VREDANDVS V1, V2, V0, V3 // d7a12004 + VREDORVS V1, V2, V3 // d7a1200a + VREDORVS V1, V2, V0, V3 // d7a12008 + VREDXORVS V1, V2, V3 // d7a1200e + VREDXORVS V1, V2, V0, V3 // d7a1200c + + // 31.14.2: Vector Widening Integer Reduction Instructions + VWREDSUMUVS V1, V2, V3 // d78120c2 + VWREDSUMUVS V1, V2, V0, V3 // d78120c0 + VWREDSUMVS V1, V2, V3 // d78120c6 + VWREDSUMVS V1, V2, V0, V3 // d78120c4 + + // 31.14.3: Vector Single-Width Floating-Point Reduction Instructions + VFREDOSUMVS V1, V2, V3 // d791200e + VFREDOSUMVS V1, V2, V0, V3 // d791200c + VFREDUSUMVS V1, V2, V3 // d7912006 + VFREDUSUMVS V1, V2, V0, V3 // d7912004 + VFREDMAXVS V1, V2, V3 // d791201e + VFREDMAXVS V1, V2, V0, V3 // d791201c + VFREDMINVS V1, V2, V3 // d7912016 + VFREDMINVS V1, V2, V0, V3 // d7912014 + + // 31.14.4: Vector Widening Floating-Point Reduction Instructions + VFWREDOSUMVS V1, V2, V3 // d79120ce + VFWREDOSUMVS V1, V2, V0, V3 // d79120cc + VFWREDUSUMVS V1, V2, V3 // d79120c6 + VFWREDUSUMVS V1, V2, V0, V3 // d79120c4 + + // 31.15: Vector Mask Instructions + VMANDMM V1, V2, V3 // d7a12066 + VMNANDMM V1, V2, V3 // d7a12076 + VMANDNMM V1, V2, V3 // d7a12062 + VMXORMM V1, V2, V3 // d7a1206e + VMORMM V1, V2, V3 // d7a1206a + VMNORMM V1, V2, V3 // d7a1207a + VMORNMM V1, V2, V3 // d7a12072 + VMXNORMM V1, V2, V3 // d7a1207e + VMMVM V2, V3 // d7212166 + VMCLRM V3 // d7a1316e + VMSETM V3 // d7a1317e + VMNOTM V2, V3 // d7212176 + VCPOPM V2, X10 // 57252842 + VCPOPM V2, V0, X10 // 57252840 + VFIRSTM V2, X10 // 57a52842 + VFIRSTM V2, V0, X10 // 57a52840 + VMSBFM V2, V3 // d7a12052 + VMSBFM V2, V0, V3 // d7a12050 + VMSIFM V2, V3 // d7a12152 + VMSIFM V2, V0, V3 // d7a12150 + VMSOFM V2, V3 // d7212152 + VMSOFM V2, V0, V3 // d7212150 + VIOTAM V2, V3 // d7212852 + VIOTAM V2, V0, V3 // d7212850 + VIDV V3 // d7a10852 + VIDV V0, V3 // d7a10850 + + // 31.16.1: Integer Scalar Move Instructions + VMVXS V2, X10 // 57252042 + VMVSX X10, V2 // 57610542 + + // 31.16.2: Floating-Point Scalar Move Instructions + VFMVFS V2, F10 // 57152042 + VFMVSF F10, V2 // 57510542 + + // 31.16.3: Vector Slide Instructions + VSLIDEUPVX X10, V2, V3 // d741253a + VSLIDEUPVX X10, V2, V0, V3 // d7412538 + VSLIDEUPVI $16, V2, V3 // d731283a + VSLIDEUPVI $16, V2, V0, V3 // d7312838 + VSLIDEDOWNVX X10, V2, V3 // d741253e + VSLIDEDOWNVX X10, V2, V0, V3 // d741253c + VSLIDEDOWNVI $16, V2, V3 // d731283e + VSLIDEDOWNVI $16, V2, V0, V3 // d731283c + VSLIDE1UPVX X10, V2, V3 // d761253a + VSLIDE1UPVX X10, V2, V0, V3 // d7612538 + VFSLIDE1UPVF F10, V2, V3 // d751253a + VFSLIDE1UPVF F10, V2, V0, V3 // d7512538 + VSLIDE1DOWNVX X10, V2, V3 // d761253e + VSLIDE1DOWNVX X10, V2, V0, V3 // d761253c + VFSLIDE1DOWNVF F10, V2, V3 // d751253e + VFSLIDE1DOWNVF F10, V2, V0, V3 // d751253c + + // 31.16.4: Vector Register Gather Instructions + VRGATHERVV V1, V2, V3 // d7812032 + VRGATHERVV V1, V2, V0, V3 // d7812030 + VRGATHEREI16VV V1, V2, V3 // d781203a + VRGATHEREI16VV V1, V2, V0, V3 // d7812038 + VRGATHERVX X10, V2, V3 // d7412532 + VRGATHERVX X10, V2, V0, V3 // d7412530 + VRGATHERVI $16, V2, V3 // d7312832 + VRGATHERVI $16, V2, V0, V3 // d7312830 + + // 31.16.5: Vector Compress Instruction + VCOMPRESSVM V1, V2, V3 // d7a1205e + + // 31.16.6: Whole Vector Register Move + VMV1RV V2, V1 // d730209e + VMV2RV V12, V10 // 57b5c09e + VMV4RV V8, V4 // 57b2819e + VMV8RV V8, V0 // 57b0839e + // // Privileged ISA // @@ -435,20 +1299,36 @@ start: WORD $0x9abcdef0 // WORD $2596069104 // f0debc9a // MOV pseudo-instructions - MOV X5, X6 // 13830200 - MOV $2047, X5 // 9302f07f - MOV $-2048, X5 // 93020080 - MOV $2048, X5 // b71200009b820280 - MOV $-2049, X5 // b7f2ffff9b82f27f - MOV $4096, X5 // b7120000 - MOV $2147479552, X5 // b7f2ff7f - MOV $2147483647, X5 // b70200809b82f2ff - MOV $-2147483647, X5 // b70200809b821200 + MOV X5, X6 // 13830200 + MOV $2047, X5 // 9302f07f + MOV $-2048, X5 // 93020080 + MOV $2048, X5 // b71200009b820280 + MOV $-2049, X5 // b7f2ffff9b82f27f + MOV $4096, X5 // b7120000 + MOV $0x7ffff000, X5 // MOV $2147479552, X5 // b7f2ff7f + MOV $-0x7ffff000, X5 // MOV $-2147479552, X5 // b7120080 + MOV $0x7fffffff, X5 // MOV $2147483647, X5 // b70200809b82f2ff + MOV $-0x7fffffff, X5 // MOV $-2147483647, X5 // b70200809b821200 + + // Converted to load and shift(s) + MOV $0xffffffff, X5 // MOV $4294967295, X5 // 9302f0ff93d20202 + MOV $0x100000000, X5 // MOV $4294967296, X5 // 9302100093920202 + MOV $0xfffffffffffda, X5 // MOV $4503599627370458, X5 // 9302d0fe9392d20093d2c200 + MOV $0xffffffffffffe, X5 // MOV $4503599627370494, X5 // 9302f0ff9392d20093d2c200 + MOV $0x7fffffff00000000, X5 // MOV $9223372032559808512, X5 // b70200809b82f2ff93920202 + MOV $0x8000000100000000, X5 // MOV $-9223372032559808512, X5 // b70200809b82120093920202 + MOV $0xffffffff00000000, X5 // MOV $-4294967296, X5 // 9302f0ff93920202 + MOV $0x1ffffffff0000000, X5 // MOV $2305843008945258496, X5 // 9302f0ff9392f20193d23200 + MOV $0x7fffffffffffffff, X5 // MOV $9223372036854775807, X5 // 9302f0ff93d21200 // Converted to load of symbol (AUIPC + LD) - MOV $4294967295, X5 // 9702000083b20200 - // Converted to MOV $1, X5 + SLLI $32, X5 - MOV $4294967296, X5 // 9302100093920202 + MOV $0x80000001, X5 // MOV $2147483649, X5 // 9702000083b20200 + MOV $0x100000001, X5 // MOV $4294967297, X5 // 9702000083b20200 + MOV $0x0800000010000000, X5 // MOV $576460752571858944, X5 // 9702000083b20200 + MOV $0x8000000010000000, X5 // MOV $-9223372036586340352, X5 // 9702000083b20200 + MOV $0x0abcdabcd0000000, X5 // MOV $773733740479250432, X5 // 9702000083b20200 + MOV $0x8abcdabcd0000000, X5 // MOV $-8449638296375525376, X5 // 9702000083b20200 + MOV $0xfff0000000ffffff, X5 // MOV $-4503599610593281, X5 // 9702000083b20200 MOV (X5), X6 // 03b30200 MOV 4(X5), X6 // 03b34200 @@ -482,6 +1362,9 @@ start: MOVD F0, 4(X5) // 27b20200 MOVD F0, F1 // d3000022 + // Convert to load of symbol (AUIPC + FLD) + MOVD $(709.78271289338397), F3 // 970f000087b10f00 + // TLS load with local-exec (LUI + ADDIW + ADD of TP + load) MOV tls(SB), X5 // b70f00009b8f0f00b38f4f0083b20f00 MOVB tls(SB), X5 // b70f00009b8f0f00b38f4f0083820f00 diff --git a/src/cmd/asm/internal/asm/testdata/riscv64error.s b/src/cmd/asm/internal/asm/testdata/riscv64error.s index 0b0184aa..4e6afa0a 100644 --- a/src/cmd/asm/internal/asm/testdata/riscv64error.s +++ b/src/cmd/asm/internal/asm/testdata/riscv64error.s @@ -30,6 +30,8 @@ TEXT errors(SB),$0 SLLI $64, X5, X6 // ERROR "immediate out of range 0 to 63" SRLI $64, X5, X6 // ERROR "immediate out of range 0 to 63" SRAI $64, X5, X6 // ERROR "immediate out of range 0 to 63" + BEQ X5, X6, $1 // ERROR "instruction with branch-like opcode lacks destination" + BEQ X5, X6, 31(X10) // ERROR "instruction with branch-like opcode lacks destination" RORI $-1, X5, X6 // ERROR "immediate out of range 0 to 63" SLLI $-1, X5, X6 // ERROR "immediate out of range 0 to 63" SRLI $-1, X5, X6 // ERROR "immediate out of range 0 to 63" @@ -43,7 +45,345 @@ TEXT errors(SB),$0 SRLIW $-1, X5, X6 // ERROR "immediate out of range 0 to 31" SRAIW $-1, X5, X6 // ERROR "immediate out of range 0 to 31" SD X5, 4294967296(X6) // ERROR "constant 4294967296 too large" - SRLI $1, X5, F1 // ERROR "expected integer register in rd position but got non-integer register F1" - SRLI $1, F1, X5 // ERROR "expected integer register in rs1 position but got non-integer register F1" FNES F1, (X5) // ERROR "needs an integer register output" + + // + // "V" Standard Extension for Vector Operations, Version 1.0 + // + VSETIVLI X10, E32, M2, TA, MA, X12 // ERROR "expected immediate value" + VLE8V (X10), V1, V3 // ERROR "invalid vector mask register" + VSE8V V3, V1, (X10) // ERROR "invalid vector mask register" + VLSE8V (X10), X10, V1, V3 // ERROR "invalid vector mask register" + VSSE8V V3, X11, V1, (X10) // ERROR "invalid vector mask register" + VLUXEI8V (X10), V2, V1, V3 // ERROR "invalid vector mask register" + VSUXEI8V V3, V2, V1, (X10) // ERROR "invalid vector mask register" + VLOXEI8V (X10), V2, V1, V3 // ERROR "invalid vector mask register" + VSOXEI8V V3, V2, V1, (X10) // ERROR "invalid vector mask register" + VL1RV (X10), V0, V3 // ERROR "too many operands for instruction" + VS1RV V3, V0, (X11) // ERROR "too many operands for instruction" + VADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VADDVX X10, V2, V1, V3 // ERROR "invalid vector mask register" + VADDVI $15, V4, V1, V2 // ERROR "invalid vector mask register" + VSUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSUBVX X10, V2, V1, V3 // ERROR "invalid vector mask register" + VRSUBVX X10, V2, V1, V3 // ERROR "invalid vector mask register" + VRSUBVI $15, V4, V1, V2 // ERROR "invalid vector mask register" + VNEGV V2, V3, V4 // ERROR "invalid vector mask register" + VWADDUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDUWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDUWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBUWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBUWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWADDWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWSUBWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWCVTXXV V2, V1, V3 // ERROR "invalid vector mask register" + VWCVTUXXV V2, V1, V3 // ERROR "invalid vector mask register" + VZEXTVF2 V2, V3, V4 // ERROR "invalid vector mask register" + VSEXTVF2 V2, V3, V4 // ERROR "invalid vector mask register" + VZEXTVF4 V2, V3, V4 // ERROR "invalid vector mask register" + VSEXTVF4 V2, V3, V4 // ERROR "invalid vector mask register" + VZEXTVF8 V2, V3, V4 // ERROR "invalid vector mask register" + VSEXTVF8 V2, V3, V4 // ERROR "invalid vector mask register" + VADCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register" + VADCVVM V1, V2, V3 // ERROR "invalid vector mask register" + VADCVVM V1, V2, V0, V0 // ERROR "invalid destination register V0" + VADCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register" + VADCVXM X10, V2, V3 // ERROR "invalid vector mask register" + VADCVXM X10, V2, V0, V0 // ERROR "invalid destination register V0" + VADCVIM $15, V2, V1, V3 // ERROR "invalid vector mask register" + VADCVIM $15, V2, V3 // ERROR "invalid vector mask register" + VADCVIM $15, V2, V0, V0 // ERROR "invalid destination register V0" + VMADCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMADCVVM V1, V2, V3 // ERROR "invalid vector mask register" + VMADCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMADCVXM X10, V2, V3 // ERROR "invalid vector mask register" + VMADCVIM $15, V2, V1, V3 // ERROR "invalid vector mask register" + VMADCVIM $15, V2, V3 // ERROR "invalid vector mask register" + VSBCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSBCVVM V1, V2, V3 // ERROR "invalid vector mask register" + VSBCVVM V1, V2, V0, V0 // ERROR "invalid destination register V0" + VSBCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSBCVXM X10, V2, V3 // ERROR "invalid vector mask register" + VSBCVXM X10, V2, V0, V0 // ERROR "invalid destination register V0" + VMSBCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSBCVVM V1, V2, V3 // ERROR "invalid vector mask register" + VMSBCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSBCVXM X10, V2, V3 // ERROR "invalid vector mask register" + VANDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VANDVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VANDVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VORVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VORVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VORVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VXORVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VXORVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VXORVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VNOTV V1, V2, V3 // ERROR "invalid vector mask register" + VSLLVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSLLVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSLLVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VSRLVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSRLVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSRLVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VSRAVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSRAVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSRAVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VNSRLWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VNSRLWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VNSRLWI $31, V2, V4, V3 // ERROR "invalid vector mask register" + VNSRAWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VNSRAWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VNSRAWI $31, V2, V4, V3 // ERROR "invalid vector mask register" + VNCVTXXW V2, V4, V3 // ERROR "invalid vector mask register" + VMSEQVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSEQVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSEQVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSNEVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSNEVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSNEVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLTUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLTUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLTVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLTVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLEUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLEUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLEUVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLEVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLEVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLEVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGTUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGTUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGTUVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGTVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGTVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGTVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGEVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGEUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLTVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSLTUVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGEVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMSGEUVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMINUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMINUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMINVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMINVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMAXUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMAXUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMAXVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMAXVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMULVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMULVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMULHVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMULHVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMULHUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMULHUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMULHSUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMULHSUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VDIVUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VDIVUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VDIVVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VDIVVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VREMUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREMUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VREMVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREMVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMULVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWMULVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMULUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWMULUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMULSUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWMULSUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMACCVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMACCVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VNMSACVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VNMSACVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMADDVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VNMSUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VNMSUBVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCSUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCSUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VWMACCUSVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMERGEVVM V1, V2, V3 // ERROR "invalid vector mask register" + VMERGEVVM V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMERGEVXM X10, V2, V3 // ERROR "invalid vector mask register" + VMERGEVXM X10, V2, V4, V3 // ERROR "invalid vector mask register" + VMERGEVIM $15, V2, V3 // ERROR "invalid vector mask register" + VMERGEVIM $15, V2, V4, V3 // ERROR "invalid vector mask register" + VMVVV V1, V2, V3 // ERROR "too many operands for instruction" + VMVVX X10, V2, V3 // ERROR "too many operands for instruction" + VMVVI $15, V2, V3 // ERROR "too many operands for instruction" + VSADDUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSADDUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSADDUVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VSADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSADDVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSADDVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VSSUBUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSSUBUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSSUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSSUBVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VAADDUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VAADDUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VAADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VAADDVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VASUBUVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VASUBUVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VASUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VASUBVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSMULVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSMULVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSSRLVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSSRLVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSSRLVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VSSRAVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VSSRAVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSSRAVI $15, V2, V4, V3 // ERROR "invalid vector mask register" + VNCLIPUWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VNCLIPUWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VNCLIPUWI $16, V2, V4, V3 // ERROR "invalid vector mask register" + VNCLIPWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VNCLIPWX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VNCLIPWI $16, V2, V4, V3 // ERROR "invalid vector mask register" + VFADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFADDVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFSUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFSUBVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFRSUBVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFWADDVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFWADDVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFWSUBVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFWSUBVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFWADDWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFWADDWF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFWSUBWV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFWSUBWF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFMULVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFMULVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFDIVVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFDIVVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFRDIVVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFWMULVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFWMULVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFMACCVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFMACCVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFNMACCVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFNMACCVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFMSACVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFMSACVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFNMSACVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFNMSACVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFMADDVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFMADDVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFNMADDVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFNMADDVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFMSUBVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFMSUBVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFNMSUBVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFNMSUBVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFWMACCVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFWMACCVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFWNMACCVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFWNMACCVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFWMSACVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFWMSACVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFWNMSACVV V2, V1, V4, V3 // ERROR "invalid vector mask register" + VFWNMSACVF V2, F10, V4, V3 // ERROR "invalid vector mask register" + VFSQRTV V2, V4, V3 // ERROR "invalid vector mask register" + VFRSQRT7V V2, V4, V3 // ERROR "invalid vector mask register" + VFREC7V V2, V4, V3 // ERROR "invalid vector mask register" + VFMINVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFMINVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFMAXVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFMAXVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFSGNJVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFSGNJVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFSGNJNVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFSGNJNVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFSGNJXVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFSGNJXVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFNEGV V2, V4, V3 // ERROR "invalid vector mask register" + VFABSV V2, V4, V3 // ERROR "invalid vector mask register" + VMFEQVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMFEQVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VMFNEVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMFNEVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VMFLTVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMFLTVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VMFLEVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMFLEVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VMFGTVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VMFGEVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VMFGTVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VMFGEVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFMERGEVFM X10, V2, V3 // ERROR "invalid vector mask register" + VFMERGEVFM F10, V2, V4, V3 // ERROR "invalid vector mask register" + VFCVTXUFV V2, V4, V3 // ERROR "invalid vector mask register" + VFCVTXFV V2, V4, V3 // ERROR "invalid vector mask register" + VFCVTRTZXUFV V2, V4, V3 // ERROR "invalid vector mask register" + VFCVTRTZXFV V2, V4, V3 // ERROR "invalid vector mask register" + VFCVTFXUV V2, V4, V3 // ERROR "invalid vector mask register" + VFCVTFXV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTXUFV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTXFV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTRTZXUFV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTRTZXFV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTFXUV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTFXV V2, V4, V3 // ERROR "invalid vector mask register" + VFWCVTFFV V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTXUFW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTXFW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTRTZXUFW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTRTZXFW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTFXUW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTFXW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTFFW V2, V4, V3 // ERROR "invalid vector mask register" + VFNCVTRODFFW V2, V4, V3 // ERROR "invalid vector mask register" + VREDSUMVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDMAXUVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDMAXVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDMINUVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDMINVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDANDVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDORVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VREDXORVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWREDSUMUVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VWREDSUMVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFREDOSUMVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFREDUSUMVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFREDMAXVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFREDMINVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VFWREDOSUMVS V1, V2, V4, V3 // ERROR "invalid vector mask register" + VCPOPM V2, V4, X10 // ERROR "invalid vector mask register" + VFIRSTM V2, V4, X10 // ERROR "invalid vector mask register" + VMSBFM V2, V4, V3 // ERROR "invalid vector mask register" + VMSIFM V2, V4, V3 // ERROR "invalid vector mask register" + VMSOFM V2, V4, V3 // ERROR "invalid vector mask register" + VIOTAM V2, V4, V3 // ERROR "invalid vector mask register" + VSLIDEUPVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSLIDEUPVI $16, V2, V4, V3 // ERROR "invalid vector mask register" + VSLIDEDOWNVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VSLIDEDOWNVI $16, V2, V4, V3 // ERROR "invalid vector mask register" + VSLIDE1UPVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VFSLIDE1UPVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VSLIDE1DOWNVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VFSLIDE1DOWNVF F10, V2, V4, V3 // ERROR "invalid vector mask register" + VRGATHERVV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VRGATHEREI16VV V1, V2, V4, V3 // ERROR "invalid vector mask register" + VRGATHERVX X10, V2, V4, V3 // ERROR "invalid vector mask register" + VRGATHERVI $16, V2, V4, V3 // ERROR "invalid vector mask register" + RET diff --git a/src/cmd/asm/internal/asm/testdata/riscv64validation.s b/src/cmd/asm/internal/asm/testdata/riscv64validation.s new file mode 100644 index 00000000..55bf518e --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/riscv64validation.s @@ -0,0 +1,431 @@ +// Copyright 2024 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 is for validation errors only, i.e., errors reported by the validate function. +// Negative test cases for errors generated earlier in the assembler's preprocess stage +// should be added to riscv64error.s. If they are added to this file, they will prevent +// the validate function from being run and TestRISCVValidation will report missing +// errors. + +TEXT validation(SB),$0 + SRLI $1, X5, F1 // ERROR "expected integer register in rd position but got non-integer register F1" + SRLI $1, F1, X5 // ERROR "expected integer register in rs1 position but got non-integer register F1" + + // + // "V" Standard Extension for Vector Operations, Version 1.0 + // + VSETVLI $32, E16, M1, TU, MU, X12 // ERROR "must be in range [0, 31] (5 bits)" + VSETVLI $-1, E32, M2, TA, MA, X12 // ERROR "must be in range [0, 31] (5 bits)" + VSETVL X10, X11 // ERROR "expected integer register in rs1 position" + VLE8V (X10), X10 // ERROR "expected vector register in vd position" + VLE8V (V1), V3 // ERROR "expected integer register in rs1 position" + VSE8V X10, (X10) // ERROR "expected vector register in vs1 position" + VSE8V V3, (V1) // ERROR "expected integer register in rd position" + VLSE8V (X10), V3 // ERROR "expected integer register in rs2 position" + VLSE8V (X10), X10, X11 // ERROR "expected vector register in vd position" + VLSE8V (V1), X10, V3 // ERROR "expected integer register in rs1 position" + VLSE8V (X10), V1, V0, V3 // ERROR "expected integer register in rs2 position" + VSSE8V V3, (X10) // ERROR "expected integer register in rs2 position" + VSSE8V X10, X11, (X10) // ERROR "expected vector register in vd position" + VSSE8V V3, X11, (V1) // ERROR "expected integer register in rs1 position" + VSSE8V V3, V1, V0, (X10) // ERROR "expected integer register in rs2 position" + VLUXEI8V (X10), V2, X11 // ERROR "expected vector register in vd position" + VLUXEI8V (X10), V2, X11 // ERROR "expected vector register in vd position" + VLUXEI8V (V1), V2, V3 // ERROR "expected integer register in rs1 position" + VLUXEI8V (X10), X11, V0, V3 // ERROR "expected vector register in vs2 position" + VSUXEI8V X10, V2, (X10) // ERROR "expected vector register in vd position" + VSUXEI8V V3, V2, (V1) // ERROR "expected integer register in rs1 position" + VSUXEI8V V3, X11, V0, (X10) // ERROR "expected vector register in vs2 position" + VLOXEI8V (X10), V2, X11 // ERROR "expected vector register in vd position" + VLOXEI8V (V1), V2, V3 // ERROR "expected integer register in rs1 position" + VLOXEI8V (X10), X11, V0, V3 // ERROR "expected vector register in vs2 position" + VSOXEI8V X10, V2, (X10) // ERROR "expected vector register in vd position" + VSOXEI8V V3, V2, (V1) // ERROR "expected integer register in rs1 position" + VSOXEI8V V3, X11, V0, (X10) // ERROR "expected vector register in vs2 position" + VL1RV (X10), X10 // ERROR "expected vector register in vd position" + VL1RV (V1), V3 // ERROR "expected integer register in rs1 position" + VS1RV X11, (X11) // ERROR "expected vector register in vs1 position" + VS1RV V3, (V1) // ERROR "expected integer register in rd position" + VADDVV V1, X10, V3 // ERROR "expected vector register in vs2 position" + VADDVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VADDVI $16, V4, V2 // ERROR "signed immediate 16 must be in range [-16, 15] (5 bits)" + VADDVI $-17, V4, V2 // ERROR "signed immediate -17 must be in range [-16, 15] (5 bits)" + VSUBVV V1, X10, V3 // ERROR "expected vector register in vs2 position" + VSUBVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VRSUBVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VRSUBVI $16, V4, V2 // ERROR "signed immediate 16 must be in range [-16, 15] (5 bits)" + VRSUBVI $-17, V4, V2 // ERROR "signed immediate -17 must be in range [-16, 15] (5 bits)" + VNEGV X10, V3 // ERROR "expected vector register in vs2 position" + VNEGV V2 // ERROR "expected vector register in vd position" + VWADDUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWADDUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWSUBUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWSUBUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWADDVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWADDVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWSUBVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWSUBVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWADDUWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWADDUWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWSUBUWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWSUBUWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWADDWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWADDWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWSUBWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWSUBWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWCVTXXV X10, V3 // ERROR "expected vector register in vs2 position" + VWCVTUXXV X10, V3 // ERROR "expected vector register in vs2 position" + VZEXTVF2 V2, V0, V3, V4 // ERROR "expected no register in rs3" + VZEXTVF2 X10, V3 // ERROR "expected vector register in vs2 position" + VSEXTVF2 V2, V0, V3, V4 // ERROR "expected no register in rs3" + VSEXTVF2 X10, V3 // ERROR "expected vector register in vs2 position" + VZEXTVF4 V2, V0, V3, V4 // ERROR "expected no register in rs3" + VZEXTVF4 X10, V3 // ERROR "expected vector register in vs2 position" + VSEXTVF4 V2, V0, V3, V4 // ERROR "expected no register in rs3" + VSEXTVF4 X10, V3 // ERROR "expected vector register in vs2 position" + VZEXTVF8 V2, V0, V3, V4 // ERROR "expected no register in rs3" + VZEXTVF8 X10, V3 // ERROR "expected vector register in vs2 position" + VSEXTVF8 V2, V0, V3, V4 // ERROR "expected no register in rs3" + VSEXTVF8 X10, V3 // ERROR "expected vector register in vs2 position" + VADCVVM X10, V2, V0, V3 // ERROR "expected vector register in vs1 position" + VADCVXM V1, V2, V0, V3 // ERROR "expected integer register in rs1 position" + VADCVIM $16, V2, V0, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VADCVIM $-17, V2, V0, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMADCVVM X10, V2, V0, V3 // ERROR "expected vector register in vs1 position" + VMADCVXM V1, V2, V0, V3 // ERROR "expected integer register in rs1 position" + VMADCVIM $16, V2, V0, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMADCVIM $-17, V2, V0, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMADCVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMADCVV V1, V2, V0, V3 // ERROR "expected no register in rs3" + VMADCVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMADCVX X10, V2, V0, V3 // ERROR "expected no register in rs3" + VMADCVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMADCVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMADCVI $15, V2, V0, V3 // ERROR "expected no register in rs3" + VSBCVVM X10, V2, V0, V3 // ERROR "expected vector register in vs1 position" + VSBCVXM V1, V2, V0, V3 // ERROR "expected integer register in rs1 position" + VMSBCVVM X10, V2, V0, V3 // ERROR "expected vector register in vs1 position" + VMSBCVXM V1, V2, V0, V3 // ERROR "expected integer register in rs1 position" + VMSBCVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSBCVV V1, V2, V0, V3 // ERROR "expected no register in rs3" + VMSBCVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSBCVX X10, V2, V0, V3 // ERROR "expected no register in rs3" + VANDVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VANDVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VANDVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VANDVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VORVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VORVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VORVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VORVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VXORVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VXORVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VXORVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VXORVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VNOTV V3 // ERROR "expected vector register in vd position" + VNOTV X10, V3 // ERROR "expected vector register in vs2 position" + VSLLVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSLLVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSLLVI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VSLLVI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VSRLVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSRLVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSRLVI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VSRLVI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VSRAVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSRAVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSRAVI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VSRAVI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VNSRLWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VNSRLWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VNSRLWI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VNSRLWI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VNSRAWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VNSRAWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VNSRAWI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VNSRAWI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VNCVTXXW X10, V3 // ERROR "expected vector register in vs2 position" + VMSEQVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSEQVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSEQVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSEQVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSNEVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSNEVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSNEVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSNEVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSLTUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSLTUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSLTVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSLTVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSLEUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSLEUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSLEUVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSLEUVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSLEVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMSLEVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSLEVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSLEVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSGTUVV X10, V2, V3 // ERROR "expected vector register in vs2 position" + VMSGTUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSGTUVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSGTUVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSGTVV X10, V2, V3 // ERROR "expected vector register in vs2 position" + VMSGTVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMSGTVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSGTVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSGEVV X10, V2, V3 // ERROR "expected vector register in vs2 position" + VMSGEUVV X10, V2, V3 // ERROR "expected vector register in vs2 position" + VMSLTVI $17, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSLTVI $-16, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSLTUVI $17, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSLTUVI $-16, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSGEVI $17, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSGEVI $-16, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMSGEUVI $17, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMSGEUVI $-16, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMINUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMINUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMINVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMINVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMAXUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMAXUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMAXVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMAXVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMULVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMULVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMULHVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMULHVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMULHUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMULHUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMULHSUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMULHSUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VDIVUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VDIVUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VDIVVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VDIVVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VREMUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREMUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VREMVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREMVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMULVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWMULVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMULUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWMULUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMULSUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWMULSUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMACCVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VMACCVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VNMSACVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VNMSACVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMADDVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VMADDVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VNMSUBVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VNMSUBVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMACCUVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VWMACCUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMACCVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VWMACCVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMACCSUVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VWMACCSUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VWMACCUSVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VMERGEVVM X10, V2, V0, V3 // ERROR "expected vector register in vs1 position" + VMERGEVXM V1, V2, V0, V3 // ERROR "expected integer register in rs1 position" + VMERGEVIM $16, V2, V0, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMERGEVIM $-17, V2, V0, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VMVVV X10, V3 // ERROR "expected vector register in vs1 position" + VMVVX V1, V2 // ERROR "expected integer register in rs1 position" + VMVVI $16, V2 // ERROR "signed immediate 16 must be in range [-16, 15]" + VMVVI $-17, V2 // ERROR "signed immediate -17 must be in range [-16, 15]" + VSADDUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSADDUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSADDUVI $16, V2, V3 // ERROR "signed immediate 16 must be in range [-16, 15]" + VSADDUVI $-17, V2, V3 // ERROR "signed immediate -17 must be in range [-16, 15]" + VSSUBUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSSUBUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VAADDUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VAADDUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VAADDVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VAADDVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VASUBUVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VASUBUVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VASUBVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VASUBVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSMULVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSMULVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSSRLVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSSRLVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSSRLVI $32, V2, V3 // ERROR "signed immediate 32 must be in range [0, 31]" + VSSRLVI $-1, V2, V3 // ERROR "signed immediate -1 must be in range [0, 31]" + VSSRAVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VSSRAVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSSRAVI $32, V2, V3 // ERROR "signed immediate 32 must be in range [0, 31]" + VSSRAVI $-1, V2, V3 // ERROR "signed immediate -1 must be in range [0, 31]" + VNCLIPUWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VNCLIPUWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VNCLIPUWI $32, V2, V3 // ERROR "signed immediate 32 must be in range [0, 31]" + VNCLIPUWI $-1, V2, V3 // ERROR "signed immediate -1 must be in range [0, 31]" + VNCLIPWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VNCLIPWX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VNCLIPWI $32, V2, V3 // ERROR "signed immediate 32 must be in range [0, 31]" + VNCLIPWI $-1, V2, V3 // ERROR "signed immediate -1 must be in range [0, 31]" + VFADDVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFADDVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFSUBVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFSUBVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFRSUBVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFWADDVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWADDVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFWSUBVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWSUBVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFWADDWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWADDWF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFWSUBWV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWSUBWF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFMULVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFMULVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFDIVVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFDIVVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFRDIVVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFWMULVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWMULVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFMACCVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFMACCVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFNMACCVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFNMACCVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFMSACVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFMSACVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFNMSACVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFNMSACVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFMADDVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFMADDVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFNMADDVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFNMADDVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFMSUBVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFMSUBVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFNMSUBVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFNMSUBVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFWMACCVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFWMACCVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFWNMACCVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFWNMACCVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFWMSACVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFWMSACVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFWNMSACVV V2, X10, V3 // ERROR "expected vector register in vs1 position" + VFWNMSACVF V2, X10, V3 // ERROR "expected float register in rs1 position" + VFSQRTV X10, V3 // ERROR "expected vector register in vs2 position" + VFRSQRT7V X10, V3 // ERROR "expected vector register in vs2 position" + VFREC7V X10, V3 // ERROR "expected vector register in vs2 position" + VFMINVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFMINVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFMAXVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFMAXVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFSGNJVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFSGNJVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFSGNJNVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFSGNJNVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFSGNJXVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFSGNJXVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VFNEGV V2, X10 // ERROR "expected vector register in vd position" + VFABSV V2, X10 // ERROR "expected vector register in vd position" + VMFEQVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMFEQVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VMFNEVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMFNEVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VMFLTVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMFLTVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VMFLEVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMFLEVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VMFGTVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VMFGEVF X10, V2, V3 // ERROR "expected float register in rs1 position" + VMFGTVV X10, V2, V3 // ERROR "expected vector register in vs2 position" + VMFGEVV X10, V2, V3 // ERROR "expected vector register in vs2 position" + VFCLASSV X10, V3 // ERROR "expected vector register in vs2 position" + VFMERGEVFM X10, V2, V0, V3 // ERROR "expected float register in rs1 position" + VFMVVF X10, V3 // ERROR "expected float register in rs1 position" + VFCVTXUFV X10, V3 // ERROR "expected vector register in vs2 position" + VFCVTXFV X10, V3 // ERROR "expected vector register in vs2 position" + VFCVTRTZXUFV X10, V3 // ERROR "expected vector register in vs2 position" + VFCVTRTZXFV X10, V3 // ERROR "expected vector register in vs2 position" + VFCVTFXUV X10, V3 // ERROR "expected vector register in vs2 position" + VFCVTFXV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTXUFV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTXFV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTRTZXUFV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTRTZXFV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTFXUV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTFXV X10, V3 // ERROR "expected vector register in vs2 position" + VFWCVTFFV X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTXUFW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTXFW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTRTZXUFW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTRTZXFW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTFXUW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTFXW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTFFW X10, V3 // ERROR "expected vector register in vs2 position" + VFNCVTRODFFW X10, V3 // ERROR "expected vector register in vs2 position" + VREDSUMVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDMAXUVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDMAXVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDMINUVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDMINVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDANDVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDORVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VREDXORVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWREDSUMUVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VWREDSUMVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFREDOSUMVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFREDUSUMVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFREDMAXVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFREDMINVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWREDOSUMVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VFWREDUSUMVS X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMANDMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMNANDMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMANDNMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMXORMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMORMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMNORMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMORNMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMXNORMM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMMVM V3, X10 // ERROR "expected vector register in vd position" + VMNOTM V3, X10 // ERROR "expected vector register in vd position" + VCPOPM V2, V1 // ERROR "expected integer register in rd position" + VCPOPM X11, X10 // ERROR "expected vector register in vs2 position" + VFIRSTM V2, V1 // ERROR "expected integer register in rd position" + VFIRSTM X11, X10 // ERROR "expected vector register in vs2 position" + VMSBFM X10, V3 // ERROR "expected vector register in vs2 position" + VMSIFM X10, V3 // ERROR "expected vector register in vs2 position" + VMSOFM X10, V3 // ERROR "expected vector register in vs2 position" + VIOTAM X10, V3 // ERROR "expected vector register in vs2 position" + VIDV X10 // ERROR "expected vector register in vd position" + VMVXS X11, X10 // ERROR "expected vector register in vs2 position" + VMVXS V2, V1 // ERROR "expected integer register in rd position" + VMVSX X11, X10 // ERROR "expected vector register in vd position" + VMVSX V2, V1 // ERROR "expected integer register in rs2 position" + VFMVFS X10, F10 // ERROR "expected vector register in vs2 position" + VFMVFS V2, V1 // ERROR "expected float register in rd position" + VFMVSF X10, V2 // ERROR "expected float register in rs2 position" + VFMVSF V2, V1 // ERROR "expected float register in rs2 position" + VSLIDEUPVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSLIDEUPVI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VSLIDEUPVI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VSLIDEDOWNVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VSLIDEDOWNVI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VSLIDEDOWNVI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VSLIDE1UPVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VFSLIDE1UPVF V1, V2, V3 // ERROR "expected float register in rs1 position" + VSLIDE1DOWNVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VFSLIDE1DOWNVF V1, V2, V3 // ERROR "expected float register in rs1 position" + VRGATHERVV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VRGATHEREI16VV X10, V2, V3 // ERROR "expected vector register in vs1 position" + VRGATHERVX V1, V2, V3 // ERROR "expected integer register in rs1 position" + VRGATHERVI $-1, V2, V3 // ERROR "unsigned immediate -1 must be in range [0, 31]" + VRGATHERVI $32, V2, V3 // ERROR "unsigned immediate 32 must be in range [0, 31]" + VCOMPRESSVM X10, V2, V3 // ERROR "expected vector register in vs1 position" + VMV1RV X10, V1 // ERROR "expected vector register in vs2 position" + VMV2RV X10, V10 // ERROR "expected vector register in vs2 position" + VMV4RV X10, V4 // ERROR "expected vector register in vs2 position" + VMV8RV X10, V0 // ERROR "expected vector register in vs2 position" + + RET diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index db2ee199..95a8c50d 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -401,6 +401,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- FMADDS F1, F2, F3 // b30e3012 FMSUB F4, F5, F5 // b31f5045 FMSUBS F6, F6, F7 // b30f7066 + LCDBR F0, F2 // b3130020 LPDFR F1, F2 // b3700021 LNDFR F3, F4 // b3710043 CPSDR F5, F6, F7 // b3725076 @@ -420,8 +421,8 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- KLMD R2, R8 // b93f0028 KIMD R0, R4 // b93e0004 KDSA R0, R8 // b93a0008 - KMA R2, R6, R4 // b9296024 - KMCTR R2, R6, R4 // b92d6024 + KMA R2, R6, R4 // b9296024 + KMCTR R2, R6, R4 // b92d6024 // vector add and sub instructions VAB V3, V4, V4 // e743400000f3 diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go index 9fdb7c49..2a9ebe9b 100644 --- a/src/cmd/asm/main.go +++ b/src/cmd/asm/main.go @@ -49,6 +49,7 @@ func main() { ctxt.Debugpcln = flags.DebugFlags.PCTab ctxt.IsAsm = true ctxt.Pkgpath = *flags.Importpath + ctxt.DwTextCount = objabi.DummyDwarfFunctionCountForAssembler() switch *flags.Spectre { default: log.Printf("unknown setting -spectre=%s", *flags.Spectre) diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index d2d7b894..edb910a8 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -2863,7 +2863,7 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ if ss, ok := dwarfToName[s]; ok { s = ss } - s = strings.Replace(s, " ", "", -1) + s = strings.ReplaceAll(s, " ", "") name := c.Ident("_Ctype_" + s) tt := *t typedef[name.Name] = &tt diff --git a/src/cmd/cgo/internal/swig/swig_test.go b/src/cmd/cgo/internal/swig/swig_test.go index 923378b2..603dab49 100644 --- a/src/cmd/cgo/internal/swig/swig_test.go +++ b/src/cmd/cgo/internal/swig/swig_test.go @@ -40,8 +40,9 @@ func TestCallback(t *testing.T) { } func run(t *testing.T, dir string, lto bool, args ...string) { + testenv.MustHaveGoRun(t) runArgs := append([]string{"run", "."}, args...) - cmd := exec.Command("go", runArgs...) + cmd := exec.Command(testenv.GoToolPath(t), runArgs...) cmd.Dir = dir if lto { // On the builders we're using the default /usr/bin/ld, but @@ -68,7 +69,7 @@ func run(t *testing.T, dir string, lto bool, args ...string) { func mustHaveCxx(t *testing.T) { // Ask the go tool for the CXX it's configured to use. - cxx, err := exec.Command("go", "env", "CXX").CombinedOutput() + cxx, err := exec.Command(testenv.GoToolPath(t), "env", "CXX").CombinedOutput() if err != nil { t.Fatalf("go env CXX failed: %s", err) } diff --git a/src/cmd/cgo/internal/test/issue18146.go b/src/cmd/cgo/internal/test/issue18146.go index 112b7ee2..04e5b5ff 100644 --- a/src/cmd/cgo/internal/test/issue18146.go +++ b/src/cmd/cgo/internal/test/issue18146.go @@ -11,6 +11,7 @@ package cgotest import ( "bytes" "crypto/md5" + "internal/testenv" "os" "os/exec" "runtime" @@ -73,7 +74,7 @@ func test18146(t *testing.T) { } runtime.GOMAXPROCS(threads) argv := append(os.Args, "-test.run=^$") - if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil { + if err := syscall.Exec(testenv.Executable(t), argv, os.Environ()); err != nil { t.Fatal(err) } } @@ -87,7 +88,7 @@ func test18146(t *testing.T) { args := append(append([]string(nil), os.Args[1:]...), "-test.run=^Test18146$") for n := attempts; n > 0; n-- { - cmd := exec.Command(os.Args[0], args...) + cmd := exec.Command(testenv.Executable(t), args...) cmd.Env = append(os.Environ(), "test18146=exec") buf := bytes.NewBuffer(nil) cmd.Stdout = buf diff --git a/src/cmd/cgo/internal/test/issue4029.go b/src/cmd/cgo/internal/test/issue4029.go index 506c999b..702af3f5 100644 --- a/src/cmd/cgo/internal/test/issue4029.go +++ b/src/cmd/cgo/internal/test/issue4029.go @@ -11,6 +11,7 @@ package cgotest /* #include +#include #include #cgo linux LDFLAGS: -ldl @@ -24,6 +25,7 @@ import "C" import ( "testing" + "unsafe" ) var callbacks int @@ -66,7 +68,9 @@ func loadThySelf(t *testing.T, symbol string) { } defer C.dlclose4029(this_process) - symbol_address := C.dlsym4029(this_process, C.CString(symbol)) + symCStr := C.CString(symbol) + defer C.free(unsafe.Pointer(symCStr)) + symbol_address := C.dlsym4029(this_process, symCStr) if symbol_address == 0 { t.Error("dlsym:", C.GoString(C.dlerror())) return diff --git a/src/cmd/cgo/internal/test/test.go b/src/cmd/cgo/internal/test/test.go index fcac0762..844b2dd4 100644 --- a/src/cmd/cgo/internal/test/test.go +++ b/src/cmd/cgo/internal/test/test.go @@ -1098,6 +1098,7 @@ func testErrno(t *testing.T) { func testMultipleAssign(t *testing.T) { p := C.CString("234") n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) + defer C.free(unsafe.Pointer(p)) if runtime.GOOS == "openbsd" { // Bug in OpenBSD strtol(3) - base > 36 succeeds. if (n != 0 && n != 239089) || m != 234 { @@ -1106,7 +1107,6 @@ func testMultipleAssign(t *testing.T) { } else if n != 0 || m != 234 { t.Fatal("Strtol x2: ", n, m) } - C.free(unsafe.Pointer(p)) } var ( @@ -1632,7 +1632,9 @@ func testNaming(t *testing.T) { func test6907(t *testing.T) { want := "yarn" - if got := C.GoString(C.Issue6907CopyString(want)); got != want { + s := C.Issue6907CopyString(want) + defer C.free(unsafe.Pointer(s)) + if got := C.GoString(s); got != want { t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want) } } @@ -1881,6 +1883,7 @@ func test17537(t *testing.T) { } p := (*C.char)(C.malloc(1)) + defer C.free(unsafe.Pointer(p)) *p = 17 if got, want := C.F17537(&p), C.int(17); got != want { t.Errorf("got %d, want %d", got, want) diff --git a/src/cmd/cgo/internal/testcarchive/carchive_test.go b/src/cmd/cgo/internal/testcarchive/carchive_test.go index c263b82d..155eca9a 100644 --- a/src/cmd/cgo/internal/testcarchive/carchive_test.go +++ b/src/cmd/cgo/internal/testcarchive/carchive_test.go @@ -218,7 +218,7 @@ func genHeader(t *testing.T, header, dir string) { t.Fatal(err) } - cmd := exec.Command("go", "tool", "cgo", + cmd := exec.Command(testenv.GoToolPath(t), "tool", "cgo", "-objdir", objDir, "-exportheader", header) cmd.Args = append(cmd.Args, files...) @@ -524,7 +524,7 @@ func TestEarlySignalHandler(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -674,7 +674,7 @@ func buildSignalForwardingTest(t *testing.T) { } t.Log("go build -buildmode=c-archive -o libgo2.a ./libgo2") - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") out, err := cmd.CombinedOutput() if len(out) > 0 { t.Logf("%s", out) @@ -801,7 +801,7 @@ func TestOsSignal(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "./libgo3") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo3.a", "./libgo3") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -843,7 +843,7 @@ func TestSigaltstack(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "./libgo4") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo4.a", "./libgo4") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -908,7 +908,7 @@ func TestExtar(t *testing.T) { t.Fatal(err) } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "./libgo4") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "./libgo4") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -955,7 +955,7 @@ func TestPIE(t *testing.T) { // be running this test in a GOROOT owned by root.) genHeader(t, "p.h", "./p") - cmd := exec.Command("go", "build", "-buildmode=c-archive", "./libgo") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "./libgo") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -1042,7 +1042,7 @@ func TestSIGPROF(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "./libgo6") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo6.a", "./libgo6") out, err := cmd.CombinedOutput() t.Logf("%v\n%s", cmd.Args, out) if err != nil { @@ -1089,7 +1089,7 @@ func TestCompileWithoutShared(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "./libgo2") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "./libgo2") out, err := cmd.CombinedOutput() t.Logf("%v\n%s", cmd.Args, out) if err != nil { @@ -1204,7 +1204,7 @@ func TestManyCalls(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo7.a", "./libgo7") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo7.a", "./libgo7") out, err := cmd.CombinedOutput() t.Logf("%v\n%s", cmd.Args, out) if err != nil { @@ -1259,7 +1259,7 @@ func TestPreemption(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo8.a", "./libgo8") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo8.a", "./libgo8") out, err := cmd.CombinedOutput() t.Logf("%v\n%s", cmd.Args, out) if err != nil { @@ -1309,7 +1309,7 @@ func TestDeepStack(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo9.a", "./libgo9") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo9.a", "./libgo9") out, err := cmd.CombinedOutput() t.Logf("%v\n%s", cmd.Args, out) if err != nil { @@ -1372,7 +1372,7 @@ func BenchmarkCgoCallbackMainThread(b *testing.B) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo10.a", "./libgo10") + cmd := exec.Command(testenv.GoToolPath(b), "build", "-buildmode=c-archive", "-o", "libgo10.a", "./libgo10") out, err := cmd.CombinedOutput() b.Logf("%v\n%s", cmd.Args, out) if err != nil { @@ -1414,7 +1414,7 @@ func TestSharedObject(t *testing.T) { }() } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo_s.a", "./libgo") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", "libgo_s.a", "./libgo") out, err := cmd.CombinedOutput() t.Logf("%v\n%s", cmd.Args, out) if err != nil { diff --git a/src/cmd/cgo/internal/testcshared/cshared_test.go b/src/cmd/cgo/internal/testcshared/cshared_test.go index 7e9a274d..09695956 100644 --- a/src/cmd/cgo/internal/testcshared/cshared_test.go +++ b/src/cmd/cgo/internal/testcshared/cshared_test.go @@ -407,7 +407,7 @@ func main() { argv = append(argv, "-ldflags", "-extldflags=-Wl,--export-all-symbols") } argv = append(argv, "-o", objfile, srcfile) - out, err := exec.Command("go", argv...).CombinedOutput() + out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput() if err != nil { t.Fatalf("build failure: %s\n%s\n", err, string(out)) } @@ -880,3 +880,44 @@ func TestIssue36233(t *testing.T) { t.Error("missing functions") } } + +func TestIssue68411(t *testing.T) { + globalSkip(t) + testenv.MustHaveCGO(t) + + t.Parallel() + + // Test that the export header uses a void function parameter for + // exported Go functions with no parameters. + + tmpdir := t.TempDir() + + const exportHeader = "issue68411.h" + + run(t, nil, "go", "tool", "cgo", "-exportheader", exportHeader, "-objdir", tmpdir, "./issue68411/issue68411.go") + data, err := os.ReadFile(exportHeader) + if err != nil { + t.Fatal(err) + } + + funcs := []struct{ name, signature string }{ + {"exportFuncWithNoParams", "void exportFuncWithNoParams(void)"}, + {"exportFuncWithParams", "exportFuncWithParams(GoInt a, GoInt b)"}, + } + + var found int + for line := range bytes.Lines(data) { + for _, fn := range funcs { + if bytes.Contains(line, []byte(fn.name)) { + found++ + if !bytes.Contains(line, []byte(fn.signature)) { + t.Errorf("function signature mismatch; got %q, want %q", line, fn.signature) + } + } + } + } + + if found != len(funcs) { + t.Error("missing functions") + } +} diff --git a/src/cmd/cgo/internal/testcshared/testdata/issue68411/issue68411.go b/src/cmd/cgo/internal/testcshared/testdata/issue68411/issue68411.go new file mode 100644 index 00000000..6a2be8b5 --- /dev/null +++ b/src/cmd/cgo/internal/testcshared/testdata/issue68411/issue68411.go @@ -0,0 +1,15 @@ +// Copyright 2025 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 main + +import "C" + +//export exportFuncWithNoParams +func exportFuncWithNoParams() {} + +//export exportFuncWithParams +func exportFuncWithParams(a, b int) {} + +func main() {} diff --git a/src/cmd/cgo/internal/testerrors/argposition_test.go b/src/cmd/cgo/internal/testerrors/argposition_test.go index 714f9b45..03555212 100644 --- a/src/cmd/cgo/internal/testerrors/argposition_test.go +++ b/src/cmd/cgo/internal/testerrors/argposition_test.go @@ -81,7 +81,7 @@ func TestArgumentsPositions(t *testing.T) { t.Fatal(err) } - cmd := exec.Command("go", "tool", "cgo", + cmd := exec.Command(testenv.GoToolPath(t), "tool", "cgo", "-srcdir", testdata, "-objdir", dir, "issue42580.go") diff --git a/src/cmd/cgo/internal/testerrors/badsym_test.go b/src/cmd/cgo/internal/testerrors/badsym_test.go index 6c87977b..4fd5c445 100644 --- a/src/cmd/cgo/internal/testerrors/badsym_test.go +++ b/src/cmd/cgo/internal/testerrors/badsym_test.go @@ -136,7 +136,7 @@ func TestBadSymbol(t *testing.T) { makeFile(godir, "go.mod", "module badsym") // Try to build our little package. - cmd := exec.Command("go", "build", "-ldflags=-v") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-v") cmd.Dir = godir output, err := cmd.CombinedOutput() diff --git a/src/cmd/cgo/internal/testerrors/errors_test.go b/src/cmd/cgo/internal/testerrors/errors_test.go index 941c7eff..80d2c402 100644 --- a/src/cmd/cgo/internal/testerrors/errors_test.go +++ b/src/cmd/cgo/internal/testerrors/errors_test.go @@ -76,7 +76,7 @@ func expect(t *testing.T, errors []*regexp.Regexp, files ...string) { for _, file := range files { args = append(args, path(file)) } - cmd := exec.Command("go", args...) + cmd := exec.Command(testenv.GoToolPath(t), args...) out, err := cmd.CombinedOutput() if err == nil { t.Errorf("expected cgo to fail but it succeeded") @@ -105,10 +105,10 @@ func expect(t *testing.T, errors []*regexp.Regexp, files ...string) { func sizeofLongDouble(t *testing.T) int { testenv.MustHaveGoRun(t) testenv.MustHaveCGO(t) - cmd := exec.Command("go", "run", path("long_double_size.go")) + cmd := exec.Command(testenv.GoToolPath(t), "run", path("long_double_size.go")) out, err := cmd.CombinedOutput() if err != nil { - t.Fatalf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out) + t.Fatalf("%#q: %v:\n%s", cmd, err, out) } i, err := strconv.Atoi(strings.TrimSpace(string(out))) @@ -158,11 +158,11 @@ func TestToleratesOptimizationFlag(t *testing.T) { testenv.MustHaveCGO(t) t.Parallel() - cmd := exec.Command("go", "build", path("issue14669.go")) + cmd := exec.Command(testenv.GoToolPath(t), "build", path("issue14669.go")) cmd.Env = append(os.Environ(), "CGO_CFLAGS="+cflags) out, err := cmd.CombinedOutput() if err != nil { - t.Errorf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out) + t.Errorf("%#q: %v:\n%s", cmd, err, out) } }) } @@ -173,10 +173,10 @@ func TestMallocCrashesOnNil(t *testing.T) { testenv.MustHaveGoRun(t) t.Parallel() - cmd := exec.Command("go", "run", path("malloc.go")) + cmd := exec.Command(testenv.GoToolPath(t), "run", path("malloc.go")) out, err := cmd.CombinedOutput() if err == nil { - t.Logf("%#q:\n%s", strings.Join(cmd.Args, " "), out) + t.Logf("%#q:\n%s", cmd, out) t.Fatalf("succeeded unexpectedly") } } diff --git a/src/cmd/cgo/internal/testerrors/ptr_test.go b/src/cmd/cgo/internal/testerrors/ptr_test.go index 9a8187f5..beba0d26 100644 --- a/src/cmd/cgo/internal/testerrors/ptr_test.go +++ b/src/cmd/cgo/internal/testerrors/ptr_test.go @@ -609,7 +609,7 @@ func buildPtrTests(t *testing.T, gopath string, cgocheck2 bool) (exe string) { if cgocheck2 { exeName = "ptrtest2.exe" } - cmd := exec.Command("go", "build", "-o", exeName) + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exeName) cmd.Dir = src cmd.Env = append(os.Environ(), "GOPATH="+gopath) diff --git a/src/cmd/cgo/internal/testfortran/fortran_test.go b/src/cmd/cgo/internal/testfortran/fortran_test.go index 0eae7c5f..9ccf916d 100644 --- a/src/cmd/cgo/internal/testfortran/fortran_test.go +++ b/src/cmd/cgo/internal/testfortran/fortran_test.go @@ -75,7 +75,7 @@ func TestFortran(t *testing.T) { // Finally, run the actual test. t.Log("go", "run", "./testdata/testprog") var stdout, stderr strings.Builder - cmd := exec.Command("go", "run", "./testdata/testprog") + cmd := exec.Command(testenv.GoToolPath(t), "run", "./testdata/testprog") cmd.Stdout = &stdout cmd.Stderr = &stderr err := cmd.Run() diff --git a/src/cmd/cgo/internal/testgodefs/testgodefs_test.go b/src/cmd/cgo/internal/testgodefs/testgodefs_test.go index 8138b7fa..d68fd4fc 100644 --- a/src/cmd/cgo/internal/testgodefs/testgodefs_test.go +++ b/src/cmd/cgo/internal/testgodefs/testgodefs_test.go @@ -51,7 +51,7 @@ func TestGoDefs(t *testing.T) { } for _, fp := range filePrefixes { - cmd := exec.Command("go", "tool", "cgo", + cmd := exec.Command(testenv.GoToolPath(t), "tool", "cgo", "-godefs", "-srcdir", testdata, "-objdir", dir, @@ -60,7 +60,7 @@ func TestGoDefs(t *testing.T) { out, err := cmd.Output() if err != nil { - t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + t.Fatalf("%#q: %v\n%s", cmd, err, cmd.Stderr) } fn := fp + "_defs.go" @@ -107,10 +107,10 @@ func TestGoDefs(t *testing.T) { // instead of invoking 'go build' and the resulting binary separately, so that // this test can pass on mobile builders, which do not copy artifacts back // from remote invocations. - cmd := exec.Command("go", "run", ".") + cmd := exec.Command(testenv.GoToolPath(t), "run", ".") cmd.Env = append(os.Environ(), "GOPATH="+gopath) cmd.Dir = dir if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("%s [%s]: %v\n%s", strings.Join(cmd.Args, " "), dir, err, out) + t.Fatalf("%#q [%s]: %v\n%s", cmd, dir, err, out) } } diff --git a/src/cmd/cgo/internal/testlife/life_test.go b/src/cmd/cgo/internal/testlife/life_test.go index e93d29c4..3b8f5709 100644 --- a/src/cmd/cgo/internal/testlife/life_test.go +++ b/src/cmd/cgo/internal/testlife/life_test.go @@ -50,7 +50,7 @@ func TestTestRun(t *testing.T) { testenv.MustHaveGoRun(t) testenv.MustHaveCGO(t) - cmd := exec.Command("go", "run", "main.go") + cmd := exec.Command(testenv.GoToolPath(t), "run", "main.go") got, err := cmd.CombinedOutput() if err != nil { t.Fatalf("%v: %s\n%s", cmd, err, got) diff --git a/src/cmd/cgo/internal/testplugin/plugin_test.go b/src/cmd/cgo/internal/testplugin/plugin_test.go index 85dfd311..d2d998e5 100644 --- a/src/cmd/cgo/internal/testplugin/plugin_test.go +++ b/src/cmd/cgo/internal/testplugin/plugin_test.go @@ -145,8 +145,8 @@ func goCmd(t *testing.T, op string, args ...string) string { // escape converts a string to something suitable for a shell command line. func escape(s string) string { - s = strings.Replace(s, "\\", "\\\\", -1) - s = strings.Replace(s, "'", "\\'", -1) + s = strings.ReplaceAll(s, "\\", "\\\\") + s = strings.ReplaceAll(s, "'", "\\'") // Conservative guess at characters that will force quoting if s == "" || strings.ContainsAny(s, "\\ ;#*&$~?!|[]()<>{}`") { s = "'" + s + "'" @@ -194,10 +194,10 @@ func run(t *testing.T, bin string, args ...string) string { out, err := cmd.Output() if err != nil { if t == nil { - log.Panicf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + log.Panicf("%#q: %v\n%s", cmd, err, cmd.Stderr) } else { t.Helper() - t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + t.Fatalf("%#q: %v\n%s", cmd, err, cmd.Stderr) } } @@ -245,7 +245,7 @@ func TestIssue18676(t *testing.T) { cmd := exec.CommandContext(ctx, "./issue18676.exe") out, err := cmd.CombinedOutput() if err != nil { - t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out) + t.Fatalf("%#q: %v\n%s", cmd, err, out) } } diff --git a/src/cmd/cgo/internal/testsanitizers/asan_test.go b/src/cmd/cgo/internal/testsanitizers/asan_test.go index 2cd2abde..cb7d8572 100644 --- a/src/cmd/cgo/internal/testsanitizers/asan_test.go +++ b/src/cmd/cgo/internal/testsanitizers/asan_test.go @@ -8,6 +8,7 @@ package sanitizers_test import ( "bytes" + "crypto/fips140" "fmt" "internal/platform" "internal/testenv" @@ -73,11 +74,11 @@ func TestASAN(t *testing.T) { !strings.Contains(out, noSymbolizer) && compilerSupportsLocation() { - t.Errorf("%#q exited without expected location of the error\n%s; got failure\n%s", strings.Join(cmd.Args, " "), tc.errorLocation, out) + t.Errorf("%#q exited without expected location of the error\n%s; got failure\n%s", cmd, tc.errorLocation, out) } return } - t.Fatalf("%#q exited without expected memory access error\n%s; got failure\n%s", strings.Join(cmd.Args, " "), tc.memoryAccessError, out) + t.Fatalf("%#q exited without expected memory access error\n%s; got failure\n%s", cmd, tc.memoryAccessError, out) } mustRun(t, cmd) }) @@ -137,6 +138,9 @@ func TestASANFuzz(t *testing.T) { if bytes.Contains(out, []byte("AddressSanitizer")) { t.Error(`output contains "AddressSanitizer", but should not`) } + if !bytes.Contains(out, []byte("FUZZ FAILED")) { + t.Error(`fuzz test did not fail with a "FUZZ FAILED" sentinel error`) + } } func mustHaveASAN(t *testing.T) *config { @@ -154,6 +158,10 @@ func mustHaveASAN(t *testing.T) *config { t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch) } + if fips140.Enabled() { + t.Skipf("skipping with FIPS 140 mode; -asan option is not supported.") + } + // The current implementation is only compatible with the ASan library from version // v7 to v9 (See the description in src/runtime/asan/asan.go). Therefore, using the // -asan option must use a compatible version of ASan library, which requires that diff --git a/src/cmd/cgo/internal/testsanitizers/cc_test.go b/src/cmd/cgo/internal/testsanitizers/cc_test.go index 63ec9cd5..f2239fb9 100644 --- a/src/cmd/cgo/internal/testsanitizers/cc_test.go +++ b/src/cmd/cgo/internal/testsanitizers/cc_test.go @@ -266,7 +266,12 @@ func compilerSupportsLocation() bool { } switch compiler.name { case "gcc": - return compiler.major >= 10 + // TODO(72752): the asan runtime support library + // (libasan.so.6) shipped with GCC 10 has problems digesting + // version 5 DWARF produced by the Go toolchain. Disable + // location checking if gcc is not sufficiently up to date in + // this case. + return compiler.major > 10 case "clang": // TODO(65606): The clang toolchain on the LUCI builders is not built against // zlib, the ASAN runtime can't actually symbolize its own stack trace. Once @@ -328,6 +333,12 @@ func compilerRequiredAsanVersion(goos, goarch string) bool { } } +// compilerRequiredLsanVersion reports whether the compiler is the +// version required by Lsan. +func compilerRequiredLsanVersion(goos, goarch string) bool { + return compilerRequiredAsanVersion(goos, goarch) +} + type compilerCheck struct { once sync.Once err error @@ -355,10 +366,18 @@ func configure(sanitizer string) *config { return c } + sanitizerOpt := sanitizer + // For the leak detector, we use "go build -asan", + // which implies the address sanitizer. + // We may want to adjust this someday. + if sanitizer == "leak" { + sanitizerOpt = "address" + } + c := &config{ sanitizer: sanitizer, - cFlags: []string{"-fsanitize=" + sanitizer}, - ldFlags: []string{"-fsanitize=" + sanitizer}, + cFlags: []string{"-fsanitize=" + sanitizerOpt}, + ldFlags: []string{"-fsanitize=" + sanitizerOpt}, } if testing.Verbose() { @@ -377,7 +396,7 @@ func configure(sanitizer string) *config { c.ldFlags = append(c.ldFlags, "-fPIC", "-static-libtsan") } - case "address": + case "address", "leak": c.goFlags = append(c.goFlags, "-asan") // Set the debug mode to print the C stack trace. c.cFlags = append(c.cFlags, "-g") @@ -475,7 +494,7 @@ func (c *config) checkCSanitizer() (skip bool, err error) { bytes.Contains(out, []byte("unsupported"))) { return true, errors.New(string(out)) } - return true, fmt.Errorf("%#q failed: %v\n%s", strings.Join(cmd.Args, " "), err, out) + return true, fmt.Errorf("%#q failed: %v\n%s", cmd, err, out) } if c.sanitizer == "fuzzer" { @@ -485,10 +504,10 @@ func (c *config) checkCSanitizer() (skip bool, err error) { if out, err := exec.Command(dst).CombinedOutput(); err != nil { if os.IsNotExist(err) { - return true, fmt.Errorf("%#q failed to produce executable: %v", strings.Join(cmd.Args, " "), err) + return true, fmt.Errorf("%#q failed to produce executable: %v", cmd, err) } snippet, _, _ := bytes.Cut(out, []byte("\n")) - return true, fmt.Errorf("%#q generated broken executable: %v\n%s", strings.Join(cmd.Args, " "), err, snippet) + return true, fmt.Errorf("%#q generated broken executable: %v\n%s", cmd, err, snippet) } return false, nil @@ -523,13 +542,12 @@ func (c *config) checkRuntime() (skip bool, err error) { return false, err } cmd.Args = append(cmd.Args, "-dM", "-E", "../../../../runtime/cgo/libcgo.h") - cmdStr := strings.Join(cmd.Args, " ") out, err := cmd.CombinedOutput() if err != nil { - return false, fmt.Errorf("%#q exited with %v\n%s", cmdStr, err, out) + return false, fmt.Errorf("%#q exited with %v\n%s", cmd, err, out) } if !bytes.Contains(out, []byte("#define CGO_TSAN")) { - return true, fmt.Errorf("%#q did not define CGO_TSAN", cmdStr) + return true, fmt.Errorf("%#q did not define CGO_TSAN", cmd) } return false, nil } diff --git a/src/cmd/cgo/internal/testsanitizers/libfuzzer_test.go b/src/cmd/cgo/internal/testsanitizers/libfuzzer_test.go index 85c8f7bb..9f548d66 100644 --- a/src/cmd/cgo/internal/testsanitizers/libfuzzer_test.go +++ b/src/cmd/cgo/internal/testsanitizers/libfuzzer_test.go @@ -95,6 +95,8 @@ func libFuzzerSupported(goos, goarch string) bool { default: return false } + case "loong64": + return true default: return false } diff --git a/src/cmd/cgo/internal/testsanitizers/lsan_test.go b/src/cmd/cgo/internal/testsanitizers/lsan_test.go new file mode 100644 index 00000000..4dde3d20 --- /dev/null +++ b/src/cmd/cgo/internal/testsanitizers/lsan_test.go @@ -0,0 +1,102 @@ +// Copyright 2025 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. + +//go:build linux || (freebsd && amd64) + +package sanitizers_test + +import ( + "internal/platform" + "internal/testenv" + "strings" + "testing" +) + +func TestLSAN(t *testing.T) { + config := mustHaveLSAN(t) + + t.Parallel() + mustRun(t, config.goCmd("build", "std")) + + cases := []struct { + src string + leakError string + errorLocation string + }{ + {src: "lsan1.go", leakError: "detected memory leaks", errorLocation: "lsan1.go:11"}, + {src: "lsan2.go"}, + {src: "lsan3.go"}, + } + for _, tc := range cases { + name := strings.TrimSuffix(tc.src, ".go") + t.Run(name, func(t *testing.T) { + t.Parallel() + + dir := newTempDir(t) + defer dir.RemoveAll(t) + + outPath := dir.Join(name) + mustRun(t, config.goCmd("build", "-o", outPath, srcPath(tc.src))) + + cmd := hangProneCmd(outPath) + if tc.leakError == "" { + mustRun(t, cmd) + } else { + outb, err := cmd.CombinedOutput() + out := string(outb) + if err != nil || len(out) > 0 { + t.Logf("%s\n%v\n%s", cmd, err, out) + } + if err != nil && strings.Contains(out, tc.leakError) { + // This string is output if the + // sanitizer library needs a + // symbolizer program and can't find it. + const noSymbolizer = "external symbolizer" + if tc.errorLocation != "" && + !strings.Contains(out, tc.errorLocation) && + !strings.Contains(out, noSymbolizer) && + compilerSupportsLocation() { + + t.Errorf("output does not contain expected location of the error %q", tc.errorLocation) + } + } else { + t.Errorf("output does not contain expected leak error %q", tc.leakError) + } + + // Make sure we can disable the leak check. + cmd = hangProneCmd(outPath) + replaceEnv(cmd, "ASAN_OPTIONS", "detect_leaks=0") + mustRun(t, cmd) + } + }) + } +} + +func mustHaveLSAN(t *testing.T) *config { + testenv.MustHaveGoBuild(t) + testenv.MustHaveCGO(t) + goos, err := goEnv("GOOS") + if err != nil { + t.Fatal(err) + } + goarch, err := goEnv("GOARCH") + if err != nil { + t.Fatal(err) + } + // LSAN is a subset of ASAN, so just check for ASAN support. + if !platform.ASanSupported(goos, goarch) { + t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch) + } + + if !compilerRequiredLsanVersion(goos, goarch) { + t.Skipf("skipping on %s/%s: too old version of compiler", goos, goarch) + } + + requireOvercommit(t) + + config := configure("leak") + config.skipIfCSanitizerBroken(t) + + return config +} diff --git a/src/cmd/cgo/internal/testsanitizers/msan_test.go b/src/cmd/cgo/internal/testsanitizers/msan_test.go index 83d66f66..554cceaf 100644 --- a/src/cmd/cgo/internal/testsanitizers/msan_test.go +++ b/src/cmd/cgo/internal/testsanitizers/msan_test.go @@ -79,7 +79,7 @@ func TestMSAN(t *testing.T) { if err != nil { return } - t.Fatalf("%#q exited without error; want MSAN failure\n%s", strings.Join(cmd.Args, " "), out) + t.Fatalf("%#q exited without error; want MSAN failure\n%s", cmd, out) } mustRun(t, cmd) }) diff --git a/src/cmd/cgo/internal/testsanitizers/testdata/asan_fuzz_test.go b/src/cmd/cgo/internal/testsanitizers/testdata/asan_fuzz_test.go index fb7ebd40..1a51819d 100644 --- a/src/cmd/cgo/internal/testsanitizers/testdata/asan_fuzz_test.go +++ b/src/cmd/cgo/internal/testsanitizers/testdata/asan_fuzz_test.go @@ -24,7 +24,7 @@ func FuzzReverse(f *testing.F) { r1 := Reverse(s) r2 := Reverse(r1) if s != r2 { - t.Errorf("got %q want %q", r2, s) + t.Errorf("FUZZ FAILED: got %q want %q", r2, s) } }) } diff --git a/src/cmd/cgo/internal/testsanitizers/testdata/lsan1.go b/src/cmd/cgo/internal/testsanitizers/testdata/lsan1.go new file mode 100644 index 00000000..5f99bd48 --- /dev/null +++ b/src/cmd/cgo/internal/testsanitizers/testdata/lsan1.go @@ -0,0 +1,39 @@ +// Copyright 2025 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 main + +/* +#include + +int* test() { + return malloc(sizeof(int)); +} + +void clearStack(int n) { + if (n > 0) { + clearStack(n - 1); + } +} + +*/ +import "C" + +//go:noinline +func F() { + C.test() +} + +func clearStack(n int) { + if n > 0 { + clearStack(n - 1) + } +} + +func main() { + // Test should fail: memory allocated by C is leaked. + F() + clearStack(100) + C.clearStack(100) +} diff --git a/src/cmd/cgo/internal/testsanitizers/testdata/lsan2.go b/src/cmd/cgo/internal/testsanitizers/testdata/lsan2.go new file mode 100644 index 00000000..b904d138 --- /dev/null +++ b/src/cmd/cgo/internal/testsanitizers/testdata/lsan2.go @@ -0,0 +1,42 @@ +// Copyright 2025 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 main + +/* +#include + +int* test() { + return malloc(sizeof(int)); +} + +void clearStack(int n) { + if (n > 0) { + clearStack(n - 1); + } +} + +*/ +import "C" + +var p *C.int + +//go:noinline +func F() { + p = C.test() +} + +func clearStack(n int) { + if n > 0 { + clearStack(n - 1) + } +} + +func main() { + // Test should pass: memory allocated by C does not leak + // because a Go global variable points to it. + F() + clearStack(100) + C.clearStack(100) +} diff --git a/src/cmd/cgo/internal/testsanitizers/testdata/lsan3.go b/src/cmd/cgo/internal/testsanitizers/testdata/lsan3.go new file mode 100644 index 00000000..824e1535 --- /dev/null +++ b/src/cmd/cgo/internal/testsanitizers/testdata/lsan3.go @@ -0,0 +1,46 @@ +// Copyright 2025 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 main + +/* +#include + +int* test() { + return malloc(sizeof(int)); +} + +void clearStack(int n) { + if (n > 0) { + clearStack(n - 1); + } +} + +*/ +import "C" + +type S struct { + p *C.int +} + +var p *S + +//go:noinline +func F() { + p = &S{p: C.test()} +} + +func clearStack(n int) { + if n > 0 { + clearStack(n - 1) + } +} + +func main() { + // Test should pass: memory allocated by C does not leak + // because a Go global variable points to it. + F() + clearStack(100) + C.clearStack(100) +} diff --git a/src/cmd/cgo/internal/testshared/shared_test.go b/src/cmd/cgo/internal/testshared/shared_test.go index 814b9994..e9274603 100644 --- a/src/cmd/cgo/internal/testshared/shared_test.go +++ b/src/cmd/cgo/internal/testshared/shared_test.go @@ -79,10 +79,10 @@ func goCmd(t *testing.T, args ...string) string { if err != nil { if t != nil { t.Helper() - t.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) + t.Fatalf("executing %#q failed %v:\n%s\n%s", c, err, stderr, output) } else { // Panic instead of using log.Fatalf so that deferred cleanup may run in testMain. - log.Panicf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) + log.Panicf("executing %#q failed %v:\n%s\n%s", c, err, stderr, output) } } if testing.Verbose() && t != nil { diff --git a/src/cmd/cgo/internal/testso/so_test.go b/src/cmd/cgo/internal/testso/so_test.go index e011167f..48eb97c8 100644 --- a/src/cmd/cgo/internal/testso/so_test.go +++ b/src/cmd/cgo/internal/testso/so_test.go @@ -52,11 +52,11 @@ func testSO(t *testing.T, dir string) { cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) out, err := cmd.Output() if err != nil { - t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + t.Fatalf("%#q: %v\n%s", cmd, err, cmd.Stderr) } lines := strings.Split(string(out), "\n") if len(lines) != 3 || lines[2] != "" { - t.Fatalf("Unexpected output from %s:\n%s", strings.Join(cmd.Args, " "), lines) + t.Fatalf("Unexpected output from %q:\n%s", cmd, lines) } cc := lines[0] @@ -90,9 +90,9 @@ func testSO(t *testing.T, dir string) { cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) out, err = cmd.CombinedOutput() if err != nil { - t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + t.Fatalf("%#q: %s\n%s", cmd, err, out) } - t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + t.Logf("%#q:\n%s", cmd, out) if runtime.GOOS == "aix" { // Shared object must be wrapped by an archive @@ -100,18 +100,18 @@ func testSO(t *testing.T, dir string) { cmd.Dir = modRoot out, err = cmd.CombinedOutput() if err != nil { - t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + t.Fatalf("%#q: %s\n%s", cmd, err, out) } } - cmd = exec.Command("go", "build", "-o", "main.exe", "main.go") + cmd = exec.Command(testenv.GoToolPath(t), "build", "-o", "main.exe", "main.go") cmd.Dir = modRoot cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) out, err = cmd.CombinedOutput() if err != nil { - t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + t.Fatalf("%#q: %s\n%s", cmd, err, out) } - t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + t.Logf("%#q:\n%s", cmd, out) cmd = exec.Command("./main.exe") cmd.Dir = modRoot @@ -131,7 +131,7 @@ func testSO(t *testing.T, dir string) { } out, err = cmd.CombinedOutput() if err != nil { - t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + t.Fatalf("%#q: %s\n%s", cmd, err, out) } - t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + t.Logf("%#q:\n%s", cmd, out) } diff --git a/src/cmd/cgo/internal/teststdio/stdio_test.go b/src/cmd/cgo/internal/teststdio/stdio_test.go index 3883422d..9150281a 100644 --- a/src/cmd/cgo/internal/teststdio/stdio_test.go +++ b/src/cmd/cgo/internal/teststdio/stdio_test.go @@ -59,7 +59,7 @@ func TestTestRun(t *testing.T) { file := file wantFile := strings.Replace(file, ".go", ".out", 1) t.Run(file, func(t *testing.T) { - cmd := exec.Command("go", "run", file) + cmd := exec.Command(testenv.GoToolPath(t), "run", file) got, err := cmd.CombinedOutput() if err != nil { t.Fatalf("%v: %s\n%s", cmd, err, got) diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index 939e282f..77beb099 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -390,7 +390,7 @@ func main() { // We already put _cgo_ at the beginning, so the main // concern is other cgo wrappers for the same functions. // Use the beginning of the 16 bytes hash of the input to disambiguate. - h := hash.New16() + h := hash.New32() io.WriteString(h, *importPath) var once sync.Once var wg sync.WaitGroup diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 5e67cc2d..10870b7c 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -251,8 +251,8 @@ func (p *Package) writeDefs() { } if callsMalloc && !*gccgo { - fmt.Fprint(fgo2, strings.Replace(cMallocDefGo, "PREFIX", cPrefix, -1)) - fmt.Fprint(fgcc, strings.Replace(strings.Replace(cMallocDefC, "PREFIX", cPrefix, -1), "PACKED", p.packedAttribute(), -1)) + fmt.Fprint(fgo2, strings.ReplaceAll(cMallocDefGo, "PREFIX", cPrefix)) + fmt.Fprint(fgcc, strings.ReplaceAll(strings.Replace(cMallocDefC, "PREFIX", cPrefix, -1), "PACKED", p.packedAttribute())) } if err := fgcc.Close(); err != nil { @@ -942,7 +942,9 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { // just have to agree. The gcc struct will be compiled // with __attribute__((packed)) so all padding must be // accounted for explicitly. - ctype := "struct {\n" + var ctype strings.Builder + const start = "struct {\n" + ctype.WriteString(start) gotype := new(bytes.Buffer) fmt.Fprintf(gotype, "struct {\n") off := int64(0) @@ -952,11 +954,11 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { t := p.cgoType(typ) if off%t.Align != 0 { pad := t.Align - off%t.Align - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) + fmt.Fprintf(&ctype, "\t\tchar __pad%d[%d];\n", npad, pad) off += pad npad++ } - ctype += fmt.Sprintf("\t\t%s %s;\n", t.C, name) + fmt.Fprintf(&ctype, "\t\t%s %s;\n", t.C, name) fmt.Fprintf(gotype, "\t\t%s ", name) noSourceConf.Fprint(gotype, fset, typ) fmt.Fprintf(gotype, "\n") @@ -974,10 +976,10 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { func(i int, aname string, atype ast.Expr) { argField(atype, "r%d", i) }) - if ctype == "struct {\n" { - ctype += "\t\tchar unused;\n" // avoid empty struct + if ctype.Len() == len(start) { + ctype.WriteString("\t\tchar unused;\n") // avoid empty struct } - ctype += "\t}" + ctype.WriteString("\t}") fmt.Fprintf(gotype, "\t}") // Get the return type of the wrapper function @@ -1007,19 +1009,25 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { if goos == "windows" { gccExport = "__declspec(dllexport) " } - s := fmt.Sprintf("%s%s %s(", gccExport, gccResult, exp.ExpName) + var s strings.Builder + fmt.Fprintf(&s, "%s%s %s(", gccExport, gccResult, exp.ExpName) if fn.Recv != nil { - s += p.cgoType(fn.Recv.List[0].Type).C.String() - s += " recv" + s.WriteString(p.cgoType(fn.Recv.List[0].Type).C.String()) + s.WriteString(" recv") } - forFieldList(fntype.Params, - func(i int, aname string, atype ast.Expr) { - if i > 0 || fn.Recv != nil { - s += ", " - } - s += fmt.Sprintf("%s %s", p.cgoType(atype).C, exportParamName(aname, i)) - }) - s += ")" + + if len(fntype.Params.List) > 0 { + forFieldList(fntype.Params, + func(i int, aname string, atype ast.Expr) { + if i > 0 || fn.Recv != nil { + s.WriteString(", ") + } + fmt.Fprintf(&s, "%s %s", p.cgoType(atype).C, exportParamName(aname, i)) + }) + } else { + s.WriteString("void") + } + s.WriteByte(')') if len(exp.Doc) > 0 { fmt.Fprintf(fgcch, "\n%s", exp.Doc) @@ -1027,11 +1035,11 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprint(fgcch, "\n") } } - fmt.Fprintf(fgcch, "extern %s;\n", s) + fmt.Fprintf(fgcch, "extern %s;\n", s.String()) fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *);\n", cPrefix, exp.ExpName) fmt.Fprintf(fgcc, "\nCGO_NO_SANITIZE_THREAD") - fmt.Fprintf(fgcc, "\n%s\n", s) + fmt.Fprintf(fgcc, "\n%s\n", s.String()) fmt.Fprintf(fgcc, "{\n") fmt.Fprintf(fgcc, "\tsize_t _cgo_ctxt = _cgo_wait_runtime_init_done();\n") // The results part of the argument structure must be @@ -1043,7 +1051,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { // string.h for memset, and is also robust to C++ // types with constructors. Both GCC and LLVM optimize // this into just zeroing _cgo_a. - fmt.Fprintf(fgcc, "\ttypedef %s %v _cgo_argtype;\n", ctype, p.packedAttribute()) + fmt.Fprintf(fgcc, "\ttypedef %s %v _cgo_argtype;\n", ctype.String(), p.packedAttribute()) fmt.Fprintf(fgcc, "\tstatic _cgo_argtype _cgo_zero;\n") fmt.Fprintf(fgcc, "\t_cgo_argtype _cgo_a = _cgo_zero;\n") if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) { @@ -1094,7 +1102,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { // This unpacks the argument struct above and calls the Go function. fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype) - fmt.Fprintf(fm, "void _cgoexp%s_%s(void* p){}\n", cPrefix, exp.ExpName) + fmt.Fprintf(fm, "void _cgoexp%s_%s(void* p __attribute__((unused))){}\n", cPrefix, exp.ExpName) fmt.Fprintf(fgo2, "\t") @@ -1938,13 +1946,15 @@ const builtinExportProlog = ` #ifndef GO_CGO_GOSTRING_TYPEDEF typedef struct { const char *p; ptrdiff_t n; } _GoString_; +extern size_t _GoStringLen(_GoString_ s); +extern const char *_GoStringPtr(_GoString_ s); #endif #endif ` func (p *Package) gccExportHeaderProlog() string { - return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1) + return strings.ReplaceAll(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize)) } // gccExportHeaderProlog is written to the exported header, after the @@ -1981,10 +1991,16 @@ typedef size_t GoUintptr; typedef float GoFloat32; typedef double GoFloat64; #ifdef _MSC_VER +#if !defined(__cplusplus) || _MSVC_LANG <= 201402L #include typedef _Fcomplex GoComplex64; typedef _Dcomplex GoComplex128; #else +#include +typedef std::complex GoComplex64; +typedef std::complex GoComplex128; +#endif +#else typedef float _Complex GoComplex64; typedef double _Complex GoComplex128; #endif diff --git a/src/cmd/compile/default.pgo b/src/cmd/compile/default.pgo index 65c28706ea54aa1be9ebf05374b14eb993632599..2c2588704f3f6ee52e2f9e9e0d3a3efcc441374a 100644 GIT binary patch literal 293923 zcmV*RKwiHeiwFP!00000|Gd2icpcYuF8WQMSyRrOX{R5Mph$|eEX$H0%915TG;GVV zZ*1o}c8Z;w_wKtdiQl`9 |Kp$h!~gil|Ko4|)^pwe`9J@! z|Mh?WlkdWgi+}eV?*ge`{_3;;_|ISehGu@7`S9Nb zfA;s`li&a0k0nGY(TnI!^dZWKzC=HwjOb4c$o@Sr_j?dAxb624qKp_y3?qgUBZ!g2 zC}K3>dt`U$IEE-5oBjVdqPRzKIg$JSd&S=#PfQ^Ey*H7VL`){85L1cC#57_mF`bw} zOeSV#|2y+@7BQP}Z+Ha~bBMXbJYqgkK`bCDiG{=>qKc>{zWcrJyH}~eEhc>ZqyoEy z$R0?mC0qLrBQylzVkPk-_ii0v6|tIFLwHBS0C6p`uI&-I zqZ$b7i4D19v|3U#K+iO~j@U?SA~q9Sh^@pnqMm3Vwi7#uorJH6+%EsKq7d3m>>>6N zjcreKhkYNhpEy7?`Hv?+J4iGWhls<(5#lJ);8!4Vj5to5AX 9>q=7J&97mRu|KuBq@#F+@A~}hiO!}sV z2Er6_D(M>q1H@_MbaDoX&WxGlEONH@xjMicaxOWK{GtDm^T`VT&4mzKKvt4Zh=t@L zvWl!G7n4iKrT(V$gs;?)wd5cExQw)y@=#(qxq{3r?Um#z(p|>wEZ%O=VKv$Fo#HiQ z@mjKY9hq6P>&Xpd9l4R*L~bTMYqtnq+d}?oE4huVCmYD^ ULr4(SIDbvbLtv-oxDNbB)z>82L2YA z6TrE7t$}cxbYuXpmRuOwCDYtH MD^`bJrd*}I?Ip2r!E!x~8UWd+QR9~te)rWYg* NP2rG`<%sS%X#wlBgfBdJl;Xle{KmKsNuQ<-%?o|-^Sq;h+zZwpO>If ~;dtL{aN=>7tQ`z3o)sp6&f0yaa8PrT_7KN|J*_1O;a$}?dH;3}|r4BHcnn&ff zVRwM$QwN9&Y60cD{Wa)RNi~rRsYO&~c2-f<)M9E0wUnx%TFF{!yI+jQA-s%QPOYF; zQmd%d)EdfjE(YpaY8|zn+CbG&8!1HUY@(X{?M{KQnc6~arM6M^lxNcBPQL<)hHTev zr-B5pyCv+Pc2c{j-P9gxFV#rxqui4PVC|<4Kt{3I!|4o&QTYsOVnlR3Wc@q_wdWB zRIoUAk6xqN7xVd#UZ>jM7`j1+8&oCv*-h#eb(^|F-KFkP_o;3VsE5=e>M`YQ>4#AC zgnCLnqn=XFDO5Qup^Mg%MLn|WVeZf;MWuAnCq?f$_jiJLFS<9~hc2W0(*5ZE^Z xn8rH9eO=@GR3f{}F5DB6DbX!@(xM5LNBG!4YtPf zqP9IUT1zjZm(wfgmGmllHGPa)L$9UR(d%ioyIRsZqn^mzxq+^uH`1u0wTa$LZ=qd9 zE4OPHAa3=%DR)!_ZW~=s`}dm$8r{{l(>v&$^h|0Oy_?=cyQ+h`b?l`ZX;gabqxaK~ ziDu#e-GsIBAl*zKq7TzYuro*LV?k#$5RTI)=oZ?qxSph4Dd!H~DY}(*Rmxl|J3{m{ zeTF_upQF#y7wC&LzIztIYnSNDbVdYRp|8@{= |t-TVeKLm00egxWr?T{M#suH%G$0B3aApKEk{QJW?5kgaH%2pK zn6b<_rkokiOkgH5lbFd&=PArort36jIx~amI+F<$LtllrW-+swISel5<}&k``ApY} zcJA&9=><$>=0%mcx8=F;19*EOW2^Uzm@1|^_qxSQ=Ox}7moha>(3TzpwU%iUlD<=4 zhF6y{%b68Sn`m?F>g<09Ni`FsmCPz;HS>n=@N3X%4U?I4YZ*u5T*s_uHZXyD=bO;2 zE_?MxW)riSaj)LO*f!)=W*dXt(*;uXjB9Dy&ke9QqY!Ffwr8KdgW1XW*WWG%5qlQM zyO}-AUIsVn8kv0zX4I*`?Pq*PfIq-^&NeZq=ingY*VrtOo0&rlW|OGE9cGR&Kl15H zN10=cUjQFx91R!Ll8wz@${ahvv@jt3nWrwlHsNt;omuktf`?tx=tIiT5*paNg z8Rfdn1Zh e2SqIg>pN<`{M?JB~d@m9yj73G77w`%RE0v6I;;&TXy&IhCEpPG@JZ zGuc_rNlPs`ar>V$4V&$4*ca83iwy^}`|KQcF584TH0H7XeKyzRB C5y z9V-G#CA*Mag!M}t!c}Z$aI4wHEHdz&A-RNI%DS5EA)zBF1wEh}5$U>~?k>wIln4oh+g_sle@GeV)eGpwn)44||u`%f5tfCkc8ZyPjk*^R^|;sCpaXkrht8J!c+C!-K*W)HE4*(2;x)+bd=kdCp(*%PdPgSS9#VZFAR z`za^=v$`Whabxrp>z#ZVImMo4-6Nb8Kcyur~(WadDpYEolve3oIhUO^`0Km)HZu zPf ^1f}dxO2nX6&6?Y<>rqz0K#di*B=b*v@y^&Qq9sY}fnj z12*5@Zh`!eeZ*q=a~#5t*(dB%_8ERIBh%Otu9QR9b1&{tklty5+?(4*VAgRG^gdh} z*O&WoKdwJFfE&mS;@p;Xgy>*y2se})#tr92a3eW<;Qtc7jt}Q3ZZtQBbJVA?+&Iqp z)z$^&T(CN#05hKR`!?+DVgfgln#f_hRmN)KFoPgtHE~n8&QrN;@8|FMY20*f1~-$l zSDR}H%;IKq=q56U!)z%PxVap p0&Q)Bz&vIcL6Y;Oe+K4v)@k 9kGWv&C$C4@ z8IJZ uizK(m{I$C_+=$;`-~Ryi}))3MX|gWjglQHwAH7eaktMn zuh#*p`Nh27&tQPKgkQ=Zq0x0!!`JfYuCt6^&SU#?4Ad3;N`4i;nqR}O<-OjnS0J&D zU!R@x?YO!O5I693Jfc*70B<)im2}34*~niYE)kpf&HNVL9=ol%*^&7jyhuAid>dcS zx9^Sn2;OPnxAQyro%}9-H@}D9%Qy1-c$(SoTcOMWzKK7`2e|UT1YPV1Z!>==w}=n( zM>0S1U=Lo0&PVxU{BiyS-(vU7N&Xa{_3PzZ`mOwFelvfDKg(y-k#qcc{sMoIzr
K=cef04T7 zcQ5+i>3q=z{sI4xf5boL?c<(F^n`!PJ9@~oTt^^!*$43U!R)$v&c7&l5)|e97~U-r zN`+oRZ=sJ+CiE5h2_yLa!U%qVFp3{2OkgH5gM`6Cdzx-nNDmQ)3ih7do SOT z7YauRBZX1IXrXY7kmt(Z!Y{@O +scDVVSU8m`tn?rV^8h zmD!)GvOiaQey+*>T$}y5PC%hQ@4=VX3mb%?^ssDntWL1wV{Sm~lcH}Ged_! e`-GAMiB$5xMUlLwkH94MG*YUHI_|c89Q2*yULr zncsfBzyxWxut#WfkhzD)u%5#qwPfa|Z)(8r6&%!%2~wlrajoUNc);%yJbtnL!U3U4 zXmiWu_Mr$U2Zd(gkZ@QyA{-Tt2`<7Z=da6M-$^Z*dutA%y$RiLv--GjLTC|A3a7F^ zTZPktZ*%Veku$<$qJ=ywIHnu2{r?qw>zr_2uvLQ#!bRbda9Ow_TotYf6~uMnhEPG= z6mGTsjUz}hrXcdnB6#h#@Nv&OLKbQ_GPC49E&kMAc6WuIHula%5qMk+_k^DJh0Gl` ztmT1#1Vq08g%5?oN5bP=10AF2iSSgwyg?So&xGmZ4Dz{PZ`HZsF+ePVQs@Of>oEju zZ|DOqB+LM@3^1ig2j~k!5&!EO(6t}*hXF7U20 Cy7Ey0;?m<1&k_FTI zk{Jti82IO*4lo>svLnEIFbw=i=enp`vSP(AG81YPjD|68>)c?*Sg57y2_%rI1B}Bi zR)H%AB$6>6oWHw3Y65t1Koh~XwGbbY2Ertm45-OI1*U?}0jvTy4gMDr2AK{s0DEE- zLNj3&%!WBI*Z&OQ=Yi*W^T8LJwm`0c3FHE(goWUD1uO!;o7v~!u7YY<4F0oAz;%Bk zz6S%urBDMiFqBy>EQ95M9$kS?tR(0w!G*BkV5wE`$Q$!ffLV=v&>C0^2uf`oAbM&9 zl=ZLyGB3#maoiJiP(g2mP2k7eM4YLbn}K5pwPf+StxQJxZHA11%$>+t&Jj?y 8_VZ=zaqedXJl2~h7|*^5w1j@-PQ8E&NkY_XX;^;c@irILPBMt|Q9JHRJ7 zb8l{IkUyxB^hZZ>tERJBQo6i48wS}4yI?n @;8~DGh`(a2C#i=bO@Cy6S2(aUPv7DsUJ4Z!Cn^680iof+nhxd_r7?D{vL< zJ{7oYfWG@W+yE4I(u)g3OIRS^gj?XcVclW54R??U8imkZxCi&)0or&Cgop45(1_<_ z*v`19n m8oSSxC)smx+R}z`V_7>ZYwz+%w zK4NYPex{bJYg&@kG|EKJW{|to1gWpsPek>D2q?Fi{^9^}pqM-15q{(#(J$c#i$jph z3=oHkL6L=FVjkfZh0t(ugt(LnLVb=DM~O(cr@ 53&vb-n4z4;uoG1o1#RO@RI9Uvc-AoZTV)2lvA{OJ#>^Pzi^!W-Tri(Mgnc^&Q zwm3(eE6x+=ixnawfK8AVh?U|((GLVpg1$(s605~ybTdAUb%4d<645_hb%4jr6XvJB zX2l`ARICwe#9DEgh|EP3q~+oY?3<$yS}FP?wVusFL`QeEn3?neD?GDth(ATUZmsA# zP~9cGPFydd9lt@W@jJ}Jz}F$)Y=F2?+=R}PjJy^-8g^VQ8Ts_LnGV__q6&}YT$?-m zp;~gTaW3gBz1$PtRZ9-_9z gq`F(ivf_PE9BwiM;h*!m3{53J_cw)+!>!Ra( zx*-NTlYS4syeST*dJ!v0*C}J;y4)<67rBib9GDBU_d0kS+?dzVcrKzt|$rCE5Lr7xFkk y^icHz1LgnBb7 q*t&y 8O;^W9qXQj~!?m!oVMsj!P$`7RfX0CnY=Lb4o&D=PGcml8r-jyYaMiMmj6u zxg6&tRM9^#Rg%rb1qlJz7$9DhE=fr6It+ZRgegdur7H1?6ksicfxjwYXv%BSb?H8L zLqgwoQ@SM~IbI=PZ%aS)D*$&Sk7kl iJr*u4$9!pQ8r&3@Ps0Y0MO!8+!cpTO!7NqFiBIm{q5P2?@$fdI5+`>|O zGNzI2n jK+@Gn7^Ve)W!7e7MI1=vQ)?FQI-!dFJgqvbJj z2~*09mB-2Da!%uEi<^y?C&=Pqexf`nPx!nWbeJsLi*N@sMV=~8%iIxoX)(M%PVCG5 zxQw1I&ye@=^h|k{oDI)=(y0&gzx!RgFYFA-+43BDt~^hkFIUJ5 y`@>+1 <0bN5ZZFNAGJbWDF=n%R>^*JlhcOG0$eSR zVAjZM<#qBv57OU<{m&Dy3vOk5UvPn6FP9P< FZtv}Ao7vxbq z+W3BX8~p}!we$WK@)zYx@@07p*H3O2@%cWyc}2b|zjaM6x-J)u@kH_L42*T8E0c4< zuO3Anv3o OIa95te1Ozy}LC0J} z@5yfsmWtjf8Y~rgq@n9jzb`+K{SWEU_E7;(^|bGy{78NSZS-ULiR?#-eE|xe%Fkps zhWT91{47zX64Qz0f n9z1(;^Vp9ywIIjo@W;3JAJjHCk`RsIFH-;XJ-zua{Pj#Z8;ClpU8E*HAf z0a}zchpZblKdGEjkdR3Plvc$T&da5QB|xjCPb+7XvkD&2h(hR`(uXdi&nrlz;8iHN zpx9B&i^?;&q-1RU%gPm{l|*cP6QrvOj?K;3hst&3hJr_oZlcEuA$CidDc)AL^LLcH z%01=2@<4fr_3 TPv|UJ7D7L#Z^-v<1(<#zzkj2Ds7f3V%9qnT5Pg#d z!k~~txZ%p`!J$g>vmqgT9EOGv&Xy>IhJ}WQ9uv*Ph>*`;uLFz>p)=70X;jD)x6ZkZ zOpr!<59h9KL*3*K|ASi6ck%`*yDf!0aR+x=?es #57$5S) z2->_NZ5vhYDPK}cHVr+QjT}x0wZ;A1hEMdiBzHIl>ZFjfKyxq1#lz#?Q@OhwZY2Z6 z$sx=GRtT{vp{b$ZoOpM}Obbm%2P_Jq8KF~TBfbJP5N3vEg=UBR%WqC7VEI`f&kcFS zoICU9h31FQDN+$y5JDH-UFk8=LRN+Xw>1mog`oiVs0!R7?CDkL3|4`w##Y7Rkbg^A z61vA-QkI5lLRb<^C?I#=0C8Ce%QH4WTpq%p>MC$6LMTjqWe8=x>H?`%A#b+sVR8n& zI@C%ckQxi*HKAkp;*CRi3120y4LVl{v2~&Kp$(ySoIn}~8#&}N6=3Q@e*e$L(56s+ z?PGJuhLHG`zAWs?A2(}5@A;QS9Ku^dHXa*uI+`GD4S8UDZBUe4U@rHhTr!4d@5)`D zJ7I#fE#%3!ZR^&YXvjV0HML~T`9{LOljfe3+XZ!i`Va~#(?DoIS6N4hZV%-Mopyxs zEzg~ypor$K5blQ4K-e8ZLb` ?LMFZh%=p5D|=lyT)0Feu!i=j)Q%c1?!mC)5t5HH!akh4y5b5I5DIwm-7 z1c|IJkh&S#&Ujff)>F4anCfMLd^;2n>}bQT`uD-yR_b44I>4O}y21<)?}qM$ZUFk& z2Dl%Zg>S|-m^ODf7bZ7BdJr0ep&Lz*mMRZJD1a;i$|Jv6Xw#8>2(R2-Z>c5s$KB4- z2tE$bFP?;+Vm }`l)B>{%St@m`)HMpbk_Ase{!a>QHrNvGrMbDs2H2HI2(qN8PC#VzEN$O-ZzyqHG zV~RReou=AO?CGli^l#wbet(0Xq0Urisinkh?B9Jp2uzSW>VY2QckM2h9oiZPa^Pv& z9MuWa&sFECSf0gvwXi~+#uqM7+f9|UK(165s&9O-NUc&mZn1B`2i59gb%|QIRP8)h z=v<@bOHk ygjl97SG{yM7~iVHpN0AqL%^<3SE@d?xmD_BVYRwh zSfj30*Qx8(4e9`8FdgiddJQ_&sT Rz=`-KXwX%cTQqliDI2R0G{K znaxebBHkuQht$Jrz)pBXZ6y&5wg$pc^_YsvrsFE^+c=>H>PjJCTU0MfRR=h!o>E)Y z)2eGqr@=g kAO=hX}9MHM49QGvUp`T}=h;4iCKLhBV34fS4CeNGSq#A|9s>AbG` zKmLY#Q$;q?EZ}+qc}w*RR(I>ZtvWQkl3Frp(pNG&z#a8h&BR^xp8vHT?Djdv)kxjk z|3-E_>*X*Da4P5k_f<6H>p?U7)iV{i2P(RMJXABr$0PNzitIIQAL0UepQ_JPe-Qh* z`VYR|O@nz9Y-^?@95D162&LgB%<}FPMgV!QLP78F3~{E|CtMcp8}1kGA07}M7# `10`Zh_Kh}xU5`JoPQ(3qr#crqr u$W}#zZfH*rm2OT{F#JPAoGS+VxA*3)tnja3#Ij;!& zUepQV3&Jnjy4ySyesk*;NK}UJ=cOagT@?d$Vfa_g#G-Ij7{SP;!K@DVrx%C&(@S#y zmWDs_W%k#ETZG#1vastQ$K-4n_~qdhVT6lwPzbSc3=mg_G040H@~UtttPZaUuMPWs zybsxR;k pwj`dNvsbygtv!xgm;E_g?ESXQFF!Xo-jhC*b$>I4^(D82gUig0aLHJ?# zQTTEANx;<2UHfzRr>Ehm(z9^A{5)Kum1@1T-kQyxoj+sS)yrQ7l7XNoz5`$Dqm^lW zwSHQEZGbjV8{q>34AKT`o#zNy5U>|vkVk*-311naWkkqO4b#kXS-@@K^d3lr+#|7v zX*l8H8_;#Qwk#`BM`%HzT1>dAz>U;U2{lR^t)b~iW3;gv67?`_+UIdv_Fz&ixl&g~ zWVX$6EwjGHYZI_1Pt+!9=$1EGb8|Fv{M;G{Q#6FLI|;h&+?}dT)37XwB q zwWXLWn4x9t)x7TFD1>HenI%3;tH%-?XKQmb-~OWlH&^p56bs~e*`AoM`82{;AaN>G zp*@33$^xxQtfLPFq2Lr?Dm8z57ix>NDy=>EUA4b=yFmwZJ)Y(_^NTf4hJeeVZRfeS zUo5~C)JwFbT8&n#Rm#h><=Py1u6&$bp{>;X7ycXk^C~Sr%>7RnW~(*(*cxrE=7%!< z0KUCWvt2UhnDyEQ?GEMtSEp^%Hffj~Y#+n_Arx)awrE3Pt2RIw#c$K QKOWkjb9lR2(AkMQ0; zKsliW-g;a3xaT#w_?lc?LKm+ki$5(MEM=1nTD0QcO0G~$0O|dk&~08;jGxp_Y30%Z zwN-N*26 *O-zah@bWzonJ3z1Z7YfLFi(@s4&^yQiVr>U|B>i63ZA&fY_< zm8>V~QJq)=;gQyg1q~i+come4!K^*?zoI*Iycv3?J=aR~QoWbnTkoUy(W}WmdO(#8 z3*<7ruYO6Hg;`hqbSz__E2M4W39oygABXe*tHAZw(e@9}2kLDqU`~yG2fjE+ckST8 z`Vf7nK1_E*X2bOn`ba&<88k}Avm8e2LGj8lSX1mcwLgcnBSh=jvHCc@TpzDb&?oAX z^kdXyeTqI+_w?2@eY(DhouQ+>HB+CZ S!+)%sy}jlNc2hYinq9naxxi$sn_;u-n|y-v?e z!;ShT9SJ2zK$#R8r<5yu#bHR~QQoWv(EDp3Y|*!3owp4gTMOiRy+Plu@9 Ij-xG)MUcD}u0bc{5QQxPd1y}a#_A0rKxXfya1A3G0IhF!rK0ARts5k3} z^uySzlb|2bkLt(td<4?R^>T!I;sn+uEqXncsB==Upik+o`f2@)evsXUCDB|9 epdPfgV6YT=2yZSx-zWzXes6Wyl>reDRg~$Zysg6_q>HyDl zREESM{9G?F^6BEGMhylS>4hHq5Q=&mb`g|5Mw!vqI7ywN`WgL=0meYXld3U*56+W# z7rule(FYlWjUh%pZcEpZJJe{WPE%({_EIM0s;f;Vh8dZk!wr;P=?&;Q!uYu7C&k~& zGU{ZL9N#VeO7S|1!mu5Zz6J6<_~uGul`)7~ zZG656X5Ok(pTfs$44c+@t+CEHA=oYkue)Kr;YEkH 1OK+w*k=6sM3=$*-+uEemx1Cj4(g2tBV*!k zH+C5Q{`CI6( 3 <694nPahgR9vbgGG#(iUC4mOQV|33;gZadGYCJQXymMr3 zslYuqP#0v0S!(t&ZN{_A|M1j>i2@etF+l8X*3o@T-_d>q{GnD2BB1>|{2_nN)bXr| z-RukNn0^PoR%Q;S`kMBx6h!1 L_ zGIWCYIk~?%z`ie!ODqM(K+~aK9b}@V`{EEDYz{H&*p2K^bC`*`Oop487LG8d&?C)i zs+9~H`%$Lr8qX~m1(?yM|0 Ii(jC zgm|?~kmi_kP1Hnu8@@2loNsz#YZc}Kvx2BJoqAIN4>LeqXf86V{QdSmyjg8}p>B)K z8}v jJ47{Ry#ysWscB&*=iG@~nq(nb~fM##f JJSIob>>F1Qr=|R zn7qyA7XKCh0Y5txDi>?XKm2j4xmE6^_10`W-YWTi0PAybdU-I1b1*HC^Ws0iuYUiB zKW;NukVBYy^TmwMZJKdA$=xs0D(C&B1pH@%=_Z(?^hE8qCSRg>&~ZGm+-bvKK#vB& zc6x3%oq(##pA;mP5y2Y+bsD$B+-dGI(MZfM;9qu|PRMGjc2I7Tx3xu2GXD cm|HAOm-@^9}m=3e7`>ZBkhJNOs-NBjjFPp9Y1NgRG z(eeq=WR7LVG3RrM_4uuAg*+;m&M#1>!oVLio6Ri0Ob(0l26R1S9ya&LH`pWQQPaB@ z=XuDR(CwJ%gz}D?C(ITz)2Mdgu_j0-%~NKpdD=W<`sDc8ti(QNe&kE`J#X$)eetXp z7s+w%{%iQo1@oeL$;>7Sj}iPOjRL}oII~tB+V9Jz9htsj;^^I=wE25-_V25vTh8{I z@Zs2;jdac2K-Q7h%^T)TGe>uh@w}jP $vHrL$u<7ug)Wd x`0W_kGox $=ah{G$&hAGF>&*nr6Ku?{@^0 z>6Q;Gn+syKMJ%Qu867DwW>_<=S=MZ8j^)Xaa6yhcyct=pBX_PfM4xB55w-bNh2;iR zU(n8Ccz=PlSgo`QbKf{ZSZFP>sw{tEzY{Wbs*fU1DTG+Hwb*L+O&>y0e`$%e)UsRk z_yxS`Sn7Tp!Znt|&WtqprNCHc1yl%im-2cmU@32~JRwVW7S&ln#Q4B(w45mb{3gqze{8mp+@IX3 z1ZZ0 cwYn$c!x_S#ERkJ{Du(n&6n?~k$SbU4*AvxV?<(!SVSssPZE^D{7$HFRh zM s-2dpORpw(<4Yz0vW9kLEv0Xbp@h(|0e9XSr+qn15N zvor*V9Rl{4g)lB3w=yG<%_eYhO(!fbvwlw0Y9O>&C#_SK=ZUXEL92Dz^1{ONkj96B zKVxCMv1hGw7M=%x9_^kkkiw(*W%LCLsoWNa@I~vAb=eAVTxlR&vGB^iS1mLedd >DpjZsjWXx{(nSZaXT1UNhQ%jSes- zGBz?Ug5>g+NAQgG@&1R!K%Eeo7?~8A9GMb1Moo=Oi+JS7J#l(uMx;TU89|Yavm&T8 znjHyb!q5TcMCL{?2*|w1Vx(Nb{76Lvsm{0{g026`2)6z$kQYWWGj9>rsH(_RX+2dP zL6Tj=z%O !{~BOM`nL0J)58L1>cJD{(M ztPZV?;IuDmB3Nl;6}Yt#6f3eW;vq &; z7C9a{5ow8>j0BW>Hb6WT34}wzVp^kfIPe9my96IupUFZD#iL2$qg+f&7?x!eFY9 z4sb4l>K_>eAc6;UFGMazus~V}*h@Y+83Oil1QAYGFj;*yaxHQlTk$s{HzR0=_o8hi zcR=QN82DQeza!k2fO0!X)FePF)9*wsDR(2aEDDXxQn22O+>bnnJd8Yw)MrCR=)gUW zJc%Iey{|yxX~fRW9%MX=Jdcz_OQXG_IPLJw5Dtax9YvQ=pJ-XspZJjky>E24(k~hq zBTa(dKRO^fFq%)185Bj24346pH^;Wj$-i6yUk&(?j!65mS~7Y6MIs{;heSPW13AJD z9bjk_H4%Ux7WI7D@F %qoSDlZGbpB`b--WMfakyQ9l*8t4WND z25J%-2$?l!AIr7b0I@vkGC_Iv^(ZQ&Cq(}N4KYoOPKtW#%45RR1Zi?~N)!#(6hdrj z^fA#)OpC6jrbja}b~}N{8Wp%1QFLE^%+vs878oGTjLwQ8Xx9+1v!nm+xjhAj9c!2( z4UzlMKSAi#GKxjCt!{?f&2yuHI!hNw&5Kr&pFP(~^!d>nOht4-bVNY)Hx;-_Y<@3{ zE{aw~t36J|@4`23nTw-KqMx62A-EtzM~E(swvVwhL8^)3ha;fWMwbPgFhN=#e0W84 zWwb3C<}$Odimr~Xi6XcU9bm2d`R>@Pi#izv>!TZ@b f^h9)hXhUe8 zHB@hjo{Tzhxqw0xZJ~OvM?Iiu_^D`X^mG)j_8f&!iCJo%iMqS8D}c{NE6HZ!TokD~ zABE8Q=)eB#XFvPd1!Q}RLwIB4V)Rn9LEo-lj-oR3O7v W*!j<%9mB5@e_J5kJ(x*J6|lzY+p(Ff6o(MM6A??nUQadZQwL_UeO8+HB` z{KeB~P^xY@hcbZ77m7yuc;m;|bwWJr{aN&Rv?LZlniK04>mBP8!{t>GyjB+L8|xSA zAH#WK2E+!&f`jU>LP4YWt3k2Bu_3XcF^6U5COs^+h94gDUfBU6BVr?Cqhfd$ JJz3PNb+ZWEJZQ({wN(_+(Od7`2nAvz;A zGd3$WJ61R+7I?|W@NWAM9XlS>UR1FIMCQgOEAwI zNnRyE3Cu{D3{%1A<=lS63*c5tkY)R~jQbo0r87(_wYVE*q=lfu33>BX>dK;oW zckngn)aXmzpC;AB9BsHZh9_Muiv?x;ERUfE&x+U~2J=)|Ag_$Aimi?zc}}lEr!}#l zS|Lw}wK2?Kus~iH3vdQlAg_ mtq^u;F1(k z2wjd{i3JF@P7uEuyB511`{RvRUf_xa^3B+-*zFi{yaPnWiFac4@*n t&tEH|E2Ia; z$6JHqZEGQak@>;#$;whSfQ!txXo}#qA@SwHWMXK1DlwUuNw`JG+oSRC0FhzwzFe-% z_we|LILg4+Mm*>T1$an3{h{hOgh$3l#Ye{jLgTMNCmXXlCO$SkE?yoVA3w{UV;x>G z ObcCD{M{0dqAkU1?iXTO@Ry#msc6_%oCvN+8=EgDqZWKc6VvD7D@%i!f z{;G^g&@18#;(2z$jA WcyI>H@wg3ibC_jtUHTpP;)!@m{A4@`_2bR@$HmgAIO4)r zfoqMUHtp&7nfTdwtLpWIY9O48pZ5>_U&D8BrT#+O{;` Q#F)g`#JI$$a5c4 Rw=aOA(@bfVfdBoP-M1OjT(4U@{K-do7fUffsySbs<9?mPW+Y#0o{V0*w z@u~v1Ac0PaN__BRpe{@-O5`d2T9v5w3xGI;7bk3R&yvJa{|h`8 L^QJctD06I4o zzlNW?tPIYEhxg~Q#GkgxgVwW0J}yr PKv A%f*T|dDEr^?7 zbD|w7`zCbTlCY~_ZcS`U)F&DO{%ud7lGz#mQ(_SPBfgGaK5aT5- r?o6gR)0$ zOl%hRCH%xw`xBdm1BuN-Q{rI4MTU>0J#NU%flrG(Zk2n{=ER}I;Y46|cLKB{iKB^Q ziQ@?z|C=Y=lbI3C!~wbqt0HhBH;e5#WAo-<)I^04b6pO3W_ldLEs2wfQ;F8Z=>%?J z)az#wPqB(VXA|cVc6nkHS8+b!E$f7yy^y$=xRkh@xWokkOs*vEDOa&w^jab~IDI{F zBT>qsg7jvhLAjOi@%E*`JQu&6xRbEW)w>C#_<;rTy~O U^v)pX zQ6a=`W-GIJK_)->2ekW3k{FbyJ9I>aoSkiLyXbvW QMVqp#ZGX zq_=SCHqGx d~Y{1Iv^h)+l_DSM!y0WBSZBl{jn?x1ve#s3O zWpw}KVPilNoks(cgOY=jE3jDRkmS&00IOR!=rAmqS?l8|yD+RTt;Z+T(qK9`zu`&m zl6PYbBa&XESq`<526JT63;9MC@CWersAPX;05dvi)7{vaHn#I`rI7jW8Ep>0H3FJ{ z69#@v(vN;sfEk Dd*OFNaerd8MS)25mTHT<-vSc5jOz11v zN%_l@ZZf2Q0VhFUk<44evpaNLnQS3fC08fcByH-Iyo` q=8zDZS=L_N71lSo`>h_DHLRtJbUwN^GK1D(Vg2wReP1--4wKtE*?^leFR{timV zR^KMZ+zJK_NmLkYPX?^2D1>$-1DVD&5OyYaB~j78J2@-5CyAmO=R`BRH!2bLCWCxE zj?nV*ue-SKM*JQXxP3|Abs7l!lLxT2H6;%wk=?yJbZk!AA<;ugC*|1X!9)uk98P8o zF%&;(fqW!+$~c 7NH8ZlCVJCQ^kG%ZOFU_6)KkpkmnGBb6WiRm29 z)L?*kD%qMmjeYrVE^@UFXx4 zZzXRh?<7x)cVFV?y<|JqTMX3u$^P^J8mH5J9XfCOJkF2b!!P~C{~jd$Y*sew5*id7 zgqhZ#@2ID_4?oYBW1hZ)+@I#X`#fGi&m?`6e4GrJq)(C${9d&l@cPqa8+0cdzGj}e zJNqgAdLGbQ8-6|OM$aw5?$EJ8sG^@IOH!q&zI?mDp?Bd+r$Tlxx>qWg45D``aJNr_ z-X}Fs9i-X>D@bXMKf-5aslKUxDSUwOe*ANMtf-yfG~mndYX8)L)WDPz9 7<=Dhaq`2gOYpX&Ku@wdkl6{&@)?N0IgQt&@MDe}no1*ss< zi3w6=Y9NN9(Lh+3!kNAnrACoeDSOARN8J}u2vw)@xdRuc=3@!DYYZpwe286=^4l?e zw52KUSayewULRadsvY^-9Xi&gvU1CT5kg+3G!vv{spY9Q-V8TuXhmveYE|kqdxrJm z9RjEYvMk-}vTTkU;i$YiwI;PTHCGR0=~jVT=b!R#K-cq$``qIA`qYM$6C_zm9U<#d z8SA aQ3>j~Lc+FENHK$}JK--ndXllDtdr|?K z+OsHDx;vv2r?5QJ4iITf+38-c!vd{G?k`p8O}GjHyD#O1$-NGp_ooh|Mu<(wK+T9} zhN@24jxC6TsohF*3ad=p5u%4uhf|KpW;5ep-j*Y&ThUC@kEZf)oc1H&564oy=|1!d zb|t%t{jcG)`#c k&GDkH9CNxxj0TBnfaN^%t$e3$d`U&GI@q^_n=4fpdXm4B*R^KapM!^EA`S>}nj zO>^B22W6D$$wkX~$&}hd(R~-b5kQiedM>)vJn$!a52FwK8oYNsbtC1z7!zeTQwXp> zhtU{CdpUg^%OtZ6-AWCJ_a<+r#&C#m^vTZzXm?Uug%es3<4p&M)Dac*-IPsC6X2Nn z27GWYH5i6T_fx^lxQ*(A)PB{~|4s#KfgK?7F!gcIuN8kiUvUou#78O2t)l|>IE7iX z29kP~F(6WtG}Kk`H01^#+`Z~qYDOHx+I;|TKTnmUOVhp5z0-Ztcqqr#70S|m(?MML z8VLQ;H5jR5|8xa?#Xya38 TdX-OA(A<>^x-hR=Hi5)Q-3__WP} zGa-$2auh-n(}8{g6}U-h)G(NwMs(x^X!VAjsEgMyc>}s`OL}vyr=+K*S5PadY3bF} z^r)S^jm8V6r)Q*HK!@9ynQ3$=XQeR^UmU`-({s}K9BmI1bJOVDo0p!S#_FMHAXK1T zu7NNzJ}SN-?FTScrqR&U!t|naRT?!Mbb#tK$_ZhBI1?79m!#3Dvou|ku1zmXBcQJ& z=*!b9(ks)e(gEs=3DWAc$Jyn+c};q4`WUq??GlhgKv|!zr*IF?@8Opl(sk)ld1Klk z2@Q&meV)oyFN0+8SQVSno6}p;c0N9q+HHZnHN7nzgd4UC8`P)U1qt+k*BjE?)0?!; zS>L}mJl;MFp9S)cbb$4!fv_`;q&J6w-<9@fn(6?%)2NK<2+^CNXWE{0gS=hdn-0=L z{tmw1n7+W5YWXX3J1T?2$mysGFJudT6T0n7FXC-DytC(Lv5NV564PMrPv4ImNH3vQ zhgwODGeHMvN~26L28g|sgK6hdcROfKA4((fV->i=X&)9ROZj~y{pS{Xf7z>puW%X@ z0`_S7SlUgb>k4T*%+*33PoLuR)6TvPU+`89ZQ! vGy@@m>& zdf{3+sOZu4HpL?6%=`e}zLEC&r}J^r2m6XN5N@Us-((!Zx6=7zQMc2G^Z&2mJ2tiF zo%G#wdw7P=S4XfAV)xSb(|rO_-7eVBadp*mHXy1!o9^?U3))IN0_j2eVfs CX1P1sDj) z1gT#EUddktu73dX#EEEvT3tc*bg?E;;D4L=`T;7CP(oaRsU54`B8^Xf0c zD? X;i_#{_J0W_OCzp2TRKc_?<&q{W9*JKgYEbbjBmhM;DAK z7+WxcvHcx+l#OC||1o>T#EtX-V&(j{^Skh+aoNeTk)L6f7i2WkAo}`X3j6T|Zq80_ z`$&U1p`em{LM$W~krN9r99 zXMw;LEqdu9j{9V*_s_YYs#;oa#Kkx_(oW0$wpyW6|R zD@3g+2y&jtd%gR-ZQge8e(wSAK`%)TBA>uyAbiMs*n7l#t@Nn(dg-;&4zC!}MO^9r z0)BMNd)#|d^+NSh)v7z;l~zIviT7te{Yv#(MVv?e9{vYOKS3mG{a%B)kN3_jxj^=e zPJ)gu##{OTA}774yq(_D-ZS2_USa#izVt)*?6BgT_q=zZ`iX*AV8p;++e(BbM^wSN z;LQoD=Z>|&jQA;JE_%DX0;oENL6d^21pr#UgeeL|E_uZs0sG7oRf0G_FRPD2KjXk& z_J05KF9%JP4f=A>SA%{u=<7k#WP=6{+E!A)B>0MVv22M9)urZ4eTmk-R?xh4)GDre zF$j(qb98Znq1#I|FE@kwy7z_`l^ee4C3#KV@*<$7O0bFXvl#cp4C>q7br|U9j`yr= zg97VQ-SuLC9V003 XG+nXjAvG zx466d6EAx4pL(-%cZVFAy8}@1(wNPQpLs8r+|l=Vuat1+PI!>?+>3kdzwlzRaaPd0 z#8*KV7+-l`d*689df$29d;du~UItTD6mPgCD0dz+ab3`*&LPxLY8XXuPo^%KFc7;7 zjKir}rbU_>Y6K Ay*L5U1Vc&=};7*MO4NvXso-&qu= zrHw@oE-=ofwkftN-pJ-q(msm`RP~fp nVbwnh}&6D9P;S0R2X4gQl5kp*B&QDGB0a3)N3K8yjf1Qrjrh7{(0h?G&zy zxr5qC5wd`}9?5X>fg2CWb|Kd+0e+tE+Ak32cVNI#TPs!Xn(Nw4Nt_Uc4!l-ZxXSW> zz@R Iam%*2dP5^$JAj8sbHBvb%c_x=QT3;_lc$N%=2tFWP `6wlvO8&M+f$5;K!{EN+f#RX!7 Yfe*Vs2Mtq{w!rYN0G y=rdAY{HMXF1Bo(#AyQC$wcgw&ohD!>I4FH=85zjlS{ zL%%ZvVR85NOvxSnU43I|Q)yEv?;A_1cU`4UV)gQC6cQz;AlOY^r`kM^RZmn;RnJto z7c-Lf89{l2LIcm6)Gg{Zabdhep;Osi>Xq{z66LVqIaHCItoD}{xe$K?e|4X_rg}gX z!sz5#M`h#7#ul)u>xZ56$B=qR)v2@NNH8CpRW>_c6fTx;`l0+0wOjp|;yAZEjARuC zH<;SXI7h7~6vFv7g7PVaM&QpVEY>!FqK6V2zPQ2koZ2O8m9-jnSrDcB4 LvAxDg<=1g61{#hFXhNy53UnsP_~Wl2hOqO!qaAFB_Jb-@$Wb6+MI=N~`5L1UqP^ z>t+ @$?$g2s!^pqRsF<7&w7`TUtxMEk&%PMXc|E1Ge>& z+<2U4uiaW0C_ECFNKc~2+b7s3(+j1tMN?=&lv+9nLg1ZBzg6?K0p5LTZ`nSyPVgyY zrqOlubed^1GVMlYzwv;P^8w?Xzqn1jQD--Ye3=5r40_PlgT5|Uy0C&~CVj(#TZ+u0 z(eb%6M<<$1_ZU$ni8*vVeM?DTX`4Ykmp&=gAu@w{9(@ukDpYGkxn+JW9RM->YB$h1 zF7bT2pcI)I)C=evn5fu7`n_`zeFn|~nyxIS59<*jaw}+-&_ZG@L@`Tgp{BcxMz^$_ z#-3k0=vL76+U=!?!oC;mD`~Dxl0PN<5LVHR=%vbu6gSbUX+lUH1K%2&n*c9c*3z%+ z>uBEJhtRt*f^t1}0vl+|aoPl`jWh=9X{NEclLE&p8MpHmdK0~w#_B 1%i1@Nok~P!)dFys?uAAPzIR9H+X^)M z$lFpJ#qLap=z LfiLE#I7?duuxR-I+ku zNn<{4r)kcyL8`N70L2;lEPaj^ZSg#PRD&sCUZ5}1UGydTGL065f>6no@H;i9HD@$u zHRm*lf}7enc*?U#PSY>1Tfqae_p6DOh9Fe7t8?#G%gL#|Fb=NJSLq_@*YDt;8`MV> zT$KMvQM}{-&B_D)5wQ9M(${F|#Mn*WHQzH!rTK}a=W?(#<-}`SDzh;)Zb*KezCrJn z>I7yW{MON+nXkD?SDS{LZqXf1!HuhcO}G;bCo8$>Xrui$ElsHJ&;?cdq)W~l* *Ci3@w2%kNs zxo)tK?+RW9)y5~Z^xtIoO$vfITcIds;RA>~rJvC~^mF QnTUWT7jtBtY}fd ^ucWUuKr^jmtdWtgR@ zgfP>WgM};azoQ9*+X%|{v}88U?vJTrhA?O_GL%6=g8u}6I*b{s8z!%o&s2Sr@zfX2 zDg)uon(ML~vYWDMCYxu~l?m6qfTX(xU^vrUCQYS`psZogvm3!Qqy48aP=$nuP=WMH zuw|FXPT5GN$2N)?&5U8tCG?GzH>1H;csuCEG6W7|417{e(xRDC1z5*1+>A7y$;rn{ z&e{y>2@JyiWWiI*tn(ao7u|3K=!s1BFpetvl)C#Z{BjaAndz@2&mRUs=8J>;&eIT@ z!c1kRF?GxtbN>o_Mo>;?&}d`^Ln5WkWM(n5rJwy*`2XfGFE#IFgA4G?$Ee1t@N?kU zJlrRW7dW3No+|v$6k;ljXwcL%T_tlFWYmVhn+*d{jebHZQ3 AF-|LctYVndw)*FlEKyY(Mp4l{(~HG}#HgUDRD z!E{W1T%KK_j-u}wLD_*#fyWpu+cbmvID;#=o?uR*Q&2frPBDWf%JXHJ>9QFzsVjab zbDEJ-*8@<28~0VqZ|F~A{ns=2t*8XsPT4k7Tgd?fF<1|Qx1-;j?z0Svz&gjAXRsQ< z1?D1yT%l~#{n*yU{C-i-A0syBkK}XsSR54NSZChHf+N%y8l0DyUFuf#ZuMnmxB3br z6sY&9^FoklvkVWB50qVH&_W6?ZhN5Y8bgqBqQEhvoU^1Xzy>pbqMJdK(XKN$nCz{+ z$q-8$5uk4|{fwko@MMP*2dipxv^zM49 JKuwW z515C{Bc{dnFTd%%7rpRvUXA4}Wqiz#?@a>yD^0)RP}dw{UtkQAxV=`;JYk+P<7r9B z_#=ovW1gx9d@*2ai4;SfCw~m&3dY|W@Ug@cD+A#krpLnJnw~Q+n3v2eW|{0Y^CmYR z6{^<0W!^ET6kMN+(0hA^*CQQTn8yMYP^r2`{@M31YfOhvlG(>D+db? zR2RFu3nwtqHwisiJLo3+2=uZ65F_KG-^jM<56JhL3pSOe_@?@hIUokUX+Ew_lFdu{ z=!aTCQ|H4VX?`f5?rSs)5zJlF)Uu1pE+uBjb=GvwG)nvVj|L4K^!1=F^Pr*n{LdM_ zJcM#ePMH6NnxyMz2K7uI50cC8`vZu~^3C>TFTu%Dsg~$|Tbpi n&<#Fx z{LCkfA2X;I_%_+m<$0kGRlG5Ra* W!PB1L@5ksNx!N4^+ z?0y5Y!uNY65@`sn^bH!L b0BrCPT#+~WnthF$7T YYB`-AH)2cKJ~6@&Ht{`gZ&JoN_;c_#WS0 z-*D@t(#xe+O85ENeC@t$Ms%a}X6g0PTcx*4@01es;+$aE@0)L1U_0PLF7bbWA0PA$ zGgX_0n-2NV#FJ1DT%_&~`}ISJ9`+sa-7R^f5Q<7q6nzl-z6&26%})ITg|WY@q_t$8 zT127E bQHO7%dbX^&S0k9W4dZ?u^P#H23Gg5Ho$#IX-7?=(-&gl(R$Kwr zQ@#%eeLbj7Mrx0nLEY(lsKpZIGVV#;q1>t5seI$${zJNcZZL69U#EQ-%-jiv6)G;m zM@Uq5(4FxeP@na6SnH5B@;TpmAE~9 ; qW&4z6D!`VQtFKw5#qekihsCeLe=wlxF>h;WHU-*e{q =A zz47HxMDGZ?)&=^ZEO_4f1bONLAh7=gf4awVr{r$QJKr~{f%RSeV!`v?m$zyvJR^M{ zzBQOVV?x0{B4xMC2UYBVp?X9ZNu=zS&Ai!{)-l?b)`2grpS-lbvLfBdC@@1=DTQ-d z*$v$=mJ^JU-tW)h<7##|Tf;7s@wK&^>RalY=0fuqq0#jb#JA+8qY>;#cAmaL&wu)0 z$tZTQYKe*?CSh}50{lxA&n+)3HRjPQFZx%6vh*QD$FPTuM~p{}wfeCvKF1akIT*)E z0! ^!y;_U9-Nc(I^?MPrruEXvf$W(@2??1PKgUZX`p`g<|Egk8#>!R!y0 zvFAzr8v`hovwtboD__APOej0(R 4J2TK#Xnq9*ZapWQsBvgCb z0E)HjI#wVSnL)jtMYPl1VCt6DDmJhiSpg-JpYbcfcFovrELe0fgSwf;Np~&mCh4HI zgKje`?qmvseG5L=2_TsBnyoB8c}IZGrnK2SzfbBx9N2B_c6JB5lg%0W3xosW)J}n8 z7u(7f`9uWh-7II}+iF{(+rx5yR_ZP&cH8zyKU*b(f7#25#s9?UQmO7wF#$oc8G@8# z+p62GyQ!)&k1gY{to$*Af!fD%?XWg>l6tb5nW8SRWH>(}TfqpDN;*-d(B z#`GC{aDe5k&Ts4P=yE-aT(hFrw5VHG*pegy^eFdq`y73}K1Yi!_Sp=C=T{tLcQ67B zXS;ca`Dy91(w@@irG>hHhuFic*x2xyqJTKymXZNW)%l{Qv`FzGL^-V6I5YaCTr@vL zPSV7o!THjd{nin-mL|)fyTNpn -^U} zU_QZq@KinEB#Sq={~W$N#dfl%*&AkIo$Y%S7TdZZYu =UEFFFQ-g)3 zE7_akEPKRwjzz8G$a1{r*$eDNwu`OOjn`gcyVRG|6Ujanm0-Kf77@-igZc`4mHjhB zG5H#cV{>hw-K`PvK6S>y?eD&wy@ySzP0DWeI(vh?$)f7Bx7fUqGnU`Dz<8U@y|o-x zz)Fw??RQu-RJhBcGxwGpK3VJrAuLe$SfV3_5tR2?G}qazK`SQ@*oQ1ukf{XQBep>^ zU$a27P_sz0So2tVw%PQL-DqjjiVgM!{j{enhWi{0Rq%|Jpp__a^soYB_Dl(;iI)$3 z)@YH?#|X;j(rwv6*IBv6vemN9BKf2P^e -oOy@z>T4)#m^ zVTBd8%0I+E)Q?{HX_}$s!~E#wtM;P+sNsH0aM}#&8b9Lv=LEwD|49ERKb9YxK|R`! zYj$3=&nw|wPXuW17(Y>5+zz_2ezKbTIR9oD7IBXEXE%=A2P Y{u zUo!9+a7|H6RZLTyFRfEd^iT3X28``%1m$Eu8nsXHO9xXnvi2XdNE%EQfNTV|*S^m# z37Mw(32NU~(A4?cHT))ouGMtx7SHfwZoEcN&h(?9=qx{h;y{68wttR)vteE7W(S|> zqp@~9w$EGIW6EYs=X0(feIn-haT2N(G!1^ND&heBeE% kdH0LO(x= z33dV_%NF_3hi{i*j+VnCF7~5Cd5K>N8W-mOrT&)&f *lcYFU6Y^Vm!d7g)qawP`5OFHBPiEmPx?APiuPFVN2wTxsSW;( z*pP1aH#(c7w5k?A89zgTW0SwA_w-NT>&<>%R%M;hzgX?B7wJ6bbX~Ui#ld7=*0Wfg z_#s5M`UR3nwVYQ({%TN_e9%{gX+hikSjF88>g|4<-m=5L(|=pP0K3q;uqUF`F9=lS zl?6Ru-tFJx-|HtOZ7wiov!6CoyJ^4afa#!VpPzp#34xaKPFb6Ou&5keOb@#pEbabD zcAhzf_ujeupEqvb??2#|ET3*L9rPdaANCVuYb^jru(_87&r$yb2dBZ&;a^qKNJ1Gq z!ElVcQ8TEI`;o~%hXLXMth?ZZ|D^wvUn=XBAHx3=e%|SSCwnjBuMSs1E7s)fi=jZO z%PlTjQnoaA#YMOMv>%PA&iFaii9QgLzkz?`R{FF4{xu1UNxt{b<(c3058< hkBiO!*1(BZyz}Pt(?E zFZ%_p^Mh6)Y%dVpn?QBNkCoJ}`cd53HU9<+7ngSXulvzZ@P@yDh4jtdv6z=~GlTjT zIzBA`xBV!t(+Zk9{=5De(kO`q52ujE@x|`>@B2^4NbS4_{$piW?b{6Mhv-yf1mz>? zOzs53V?UAeR1TI$EXO&2LR=-DO0P^BLee_SGk=f&iKSaU!id@P3+wN5|2@qi)eC=7 z^QUsKy!20Uzw&Rl?XZzbD=pSd*3qS#t(^LC5eDvW;g_%dyd}>Y|428flKxGs();rs zzw zd4?iIata*70+UOQL#wu_v^p?6P!qt7jYkBy*3rlS1|c X!wvP`?2%xXk2Jnm=no#_&)|#ofqa1(`?#1;m-*n!0bdT_CcYWI?A$k}RNUAU-FHqb z>X=h14CV# ub2QXp&2+;cj*?=?~oc0lr8bNs= zfQrB!3>*p^4&cvs04k0I`T;!u9sDy6ZCk10TpqrOd1e0+1pYnIy}e;OW*i|u8W lfU7f5NV7iw89$Vt4x9oo$(8skiWvR1yMr18 blp^kl2mTIg!MxB z0z!vfQr~cZ{&C<*fM`MZ6raYNV0aej37phox|~K(K9^o`513yBhPZ~hE)Y;hR?xg8 zZvIu^o%uCBUTAQ>3H)kr$-a_;TqY}M-Ui+U5Imj(^zQ>C+|vMv4Gvy&b-S*+1lCVg za7a*Blz*9o0LRklDj6E|i@Ur9ZtPFsYkcY&7OV~q5AIgi1Uc@|Sa}|K$|XO%!({Fk zam!OQZ;l9(w1@G$ghwro3=*%J8PubK>s4r#cXV(}5PdeBU>F-D=G6?i#s#?)K+r5b zfKf%q2QkrFBPb^XB|Q)im^bIy+M^V;LCmprVi4(7l!IkbaB^@;aJYJEa9Z$j8LD<% z7i_m?qnvXN!qR94_4FW~f6NGCbx