nasm/common/common.c

81 lines
1.8 KiB
C
Raw Permalink Normal View History

/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* common.c - code common to nasm and ndisasm
*/
#include "compiler.h"
#include "nasm.h"
#include "nasmlib.h"
#include "insns.h"
/*
* Per-pass global (across segments) state
*/
struct globalopt globl;
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
void reset_global_defaults(int bits)
{
globl.bits = bits;
globl.bnd = false;
globl.rel = 0;
globl.reldef = EAF_FS|EAF_GS;
globl.dollarhex = true;
}
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
/*
* Name of a register token, if applicable; otherwise NULL
*/
const char *register_name(int token)
{
if (is_register(token))
return nasm_reg_names[token - EXPR_REG_START];
else
return NULL;
}
/*
* Common list of prefix names; ideally should be auto-generated
* from tokens.dat. This MUST match the enum in include/nasm.h.
*/
const char *prefix_name(int token)
{
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
static const char * const
prefix_names[PREFIX_ENUM_LIMIT - PREFIX_ENUM_START] = {
"a16", "a32", "a64", "asp", "lock", "o16", "o32", "o64", "osp",
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
"rep", "repe", "repne", "repnz", "repz", "wait",
"xacquire", "xrelease", "bnd", "nobnd", "{rex}", "{rex2}",
"{evex}", "{vex}", "{vex3}", "{vex2}", "{nf}", "{zu}",
"{pt}", "{pn}"
};
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
const char *name;
/* A register can also be a prefix */
name = register_name(token);
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
if (!name) {
const unsigned int prefix = token - PREFIX_ENUM_START;
if (prefix < ARRAY_SIZE(prefix_names))
name = prefix_names[prefix];
}
Major changes to a number of subsystems to improve matching Work through a number of changes toward making matching a lot saner, both to reduce the number of patterns to generate for APX but also to make a number of code patterns simpler. This replaces a fair number of byte codes. Improve a number of error messages, especially related to overflows. Move process_insn() from nasm.c to assemble.c, as it really is the primary entry point to the assembler module. Reorder some prefixes. In particular, F2/F3 override 66 when used as a mandatory prefix, so it makes more sense for them to be closer to the opcode. Move a lot more information into struct insn. It is better to have it in one place; memory consumption is not an issue because struct insn is transient information. Get rid of "optimization levels" and replace it with a mask of flags. That was already halfway done; complete the job. Replace seg:offset in struct out_data with a struct location. It would be better to extend this to more places, too. The ARx and SMx flags are now explicit bitmasks, instead of having a couple of hard-coded ranges. Add __func__ to assert or panic messages. Because of prefix and message changes, a number of travis tests had to be audited and updated. Fix a number of instruction patterns which had .128 when they ought to be .lig. This is no longer a minor issue with the disassembler: for AVX10, the pattern vector length determines how SAE/RC are encoded, and there is no valid 128-bit encoding. However, with .lig the 512-bit encoding can be used. Separate "o64nw" into two pieces: opsize 64 and "nw" = "REX.w not necessary". The latter can be included in non-64-bit patterns. "o64" still set REX.W since that is still the common thing. New "osz" bytecode: emit an OSP *or* REX.W depending on the current mode and operand size. Useful for special cases like "nop" where "o64 nop" probably wants to be encoded as "48 90". Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2024-08-07 17:13:44 -07:00
return name;
}
/*
* True for a valid hinting-NOP opcode, after 0F.
*/
bool is_hint_nop(uint64_t op)
{
if (op >> 16)
return false;
if ((op >> 8) == 0x0f)
op = (uint8_t)op;
else if (op >> 8)
return false;
return ((op & ~7) == 0x18) || (op == 0x0d);
}